NCBI C++ ToolKit
cs.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) 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 <stdarg.h>
24 
25 #include <freetds/time.h>
26 
27 #include <stdio.h>
28 #include <assert.h>
29 
30 #if HAVE_STDLIB_H
31 #include <stdlib.h>
32 #endif /* HAVE_STDLIB_H */
33 
34 #if HAVE_STRING_H
35 #include <string.h>
36 #endif /* HAVE_STRING_H */
37 
38 #include "cspublic.h"
39 #include "ctlib.h"
40 #include "replacements.h"
41 
46 
47 const char *
48 cs_prretcode(int retcode)
49 {
50  static char unknown[24];
51 
52  tdsdump_log(TDS_DBG_FUNC, "cs_prretcode(%d)\n", retcode);
53 
54  switch(retcode) {
55  case CS_SUCCEED: return "CS_SUCCEED";
56  case CS_FAIL: return "CS_FAIL";
57  case CS_MEM_ERROR: return "CS_MEM_ERROR";
58  case CS_PENDING: return "CS_PENDING";
59  case CS_QUIET: return "CS_QUIET";
60  case CS_BUSY: return "CS_BUSY";
61  case CS_INTERRUPT: return "CS_INTERRUPT";
62  case CS_BLK_HAS_TEXT: return "CS_BLK_HAS_TEXT";
63  case CS_CONTINUE: return "CS_CONTINUE";
64  case CS_FATAL: return "CS_FATAL";
65  case CS_RET_HAFAILOVER: return "CS_RET_HAFAILOVER";
66  case CS_UNSUPPORTED: return "CS_UNSUPPORTED";
67 
68  case CS_CANCELED: return "CS_CANCELED";
69  case CS_ROW_FAIL: return "CS_ROW_FAIL";
70  case CS_END_DATA: return "CS_END_DATA";
71  case CS_END_RESULTS: return "CS_END_RESULTS";
72  case CS_END_ITEM: return "CS_END_ITEM";
73  case CS_NOMSG: return "CS_NOMSG";
74  case CS_TIMED_OUT: return "CS_TIMED_OUT";
75 
76  default:
77  sprintf(unknown, "oops: %u ??", retcode);
78  }
79  return unknown;
80 }
81 
82 static const char *
83 _cs_get_layer(int layer)
84 {
85  tdsdump_log(TDS_DBG_FUNC, "_cs_get_layer(%d)\n", layer);
86 
87  switch (layer) {
88  case 2:
89  return "cslib user api layer";
90  break;
91  default:
92  break;
93  }
94  return "unrecognized layer";
95 }
96 
97 static const char *
99 {
100  tdsdump_log(TDS_DBG_FUNC, "_cs_get_origin(%d)\n", origin);
101 
102  switch (origin) {
103  case 1:
104  return "external error";
105  break;
106  case 2:
107  return "internal CS-Library error";
108  break;
109  case 4:
110  return "common library error";
111  break;
112  case 5:
113  return "intl library error";
114  break;
115  default:
116  break;
117  }
118  return "unrecognized origin";
119 }
120 
121 static const char *
123 {
124  tdsdump_log(TDS_DBG_FUNC, "_cs_get_user_api_layer_error(%d)\n", error);
125 
126  switch (error) {
127  case 3:
128  return "Memory allocation failure.";
129  break;
130  case 16:
131  return "Conversion between %1! and %2! datatypes is not supported.";
132  break;
133  case 20:
134  return "The conversion/operation resulted in overflow.";
135  break;
136  case 24:
137  return "The conversion/operation was stopped due to a syntax error in the source field.";
138  break;
139  case 25:
140  return "Data is truncated during conversion.";
141  break;
142  case 26:
143  return "Data-conversion resulted in overflow.";
144  break;
145  case 27:
146  return "Unknown callback %1!.";
147  break;
148  case 28:
149  return "Unknown size %1! for SYBINTN.";
150  break;
151  case 29:
152  return "Unknown float size of %1!.";
153  break;
154  case 30:
155  return "Unknown money size of %1!.";
156  break;
157  case 31:
158  return "Unknown date size of %1!.";
159  break;
160  case 32:
161  return "Unknown type: %1!.";
162  break;
163  case 33:
164  return "Out of memory!";
165  break;
166  default:
167  break;
168  }
169  return "unrecognized error";
170 }
171 
172 static char *
173 _cs_get_msgstr(const char *funcname, int layer, int origin, int severity, int number)
174 {
175  char *m;
176 
177  tdsdump_log(TDS_DBG_FUNC, "_cs_get_msgstr(%s, %d, %d, %d, %d)\n", funcname, layer, origin, severity, number);
178 
179  if (asprintf(&m, "%s: %s: %s: %s", funcname, _cs_get_layer(layer), _cs_get_origin(origin), (layer == 2)
181  : "unrecognized error") < 0) {
182  return NULL;
183  }
184  return m;
185 }
186 
187 void
188 _csclient_msg(CS_CONTEXT * ctx, const char *funcname, int layer, int origin, int severity, int number, const char *fmt, ...)
189 {
190  va_list ap;
191  CS_CLIENTMSG cm;
192  char *msgstr;
193 
194  tdsdump_log(TDS_DBG_FUNC, "_csclient_msg(%p, %s, %d, %d, %d, %d, %s)\n", ctx, funcname, layer, origin, severity, number, fmt);
195 
196  va_start(ap, fmt);
197 
198  if (ctx->_cslibmsg_cb) {
199  cm.severity = severity;
200  cm.msgnumber = (((layer << 24) & 0xFF000000)
201  | ((origin << 16) & 0x00FF0000)
202  | ((severity << 8) & 0x0000FF00)
203  | ((number) & 0x000000FF));
204  msgstr = _cs_get_msgstr(funcname, layer, origin, severity, number);
205  tds_vstrbuild(cm.msgstring, CS_MAX_MSG, &(cm.msgstringlen), msgstr, CS_NULLTERM, fmt, CS_NULLTERM, ap);
206  cm.msgstring[cm.msgstringlen] = '\0';
207  free(msgstr);
208  cm.osnumber = 0;
209  cm.osstring[0] = '\0';
210  cm.osstringlen = 0;
211  cm.status = 0;
212  /* cm.sqlstate */
213  cm.sqlstatelen = 0;
214  ctx->_cslibmsg_cb(ctx, &cm);
215  }
216 
217  va_end(ap);
218 }
219 
220 /**
221  * Allocate new CS_LOCALE and initialize it
222  * returns NULL on out of memory errors
223  */
224 static CS_LOCALE *
226 {
227  tdsdump_log(TDS_DBG_FUNC, "_cs_locale_alloc()\n");
228 
229  return tds_new0(CS_LOCALE, 1);
230 }
231 
232 static void
234 {
235  tdsdump_log(TDS_DBG_FUNC, "_cs_locale_free_contents(%p)\n", locale);
236 
237  /* free strings */
238  free(locale->language);
239  locale->language = NULL;
240  free(locale->charset);
241  locale->charset = NULL;
242  free(locale->time);
243  locale->time = NULL;
244  free(locale->collate);
245  locale->collate = NULL;
246 }
247 
248 void
250 {
251  tdsdump_log(TDS_DBG_FUNC, "_cs_locale_free(%p)\n", locale);
252 
253  /* free contents */
255 
256  /* free the data structure */
257  free(locale);
258 }
259 
260 /* returns 0 on out of memory errors, 1 for OK */
261 int
263 {
264  tdsdump_log(TDS_DBG_FUNC, "_cs_locale_copy_inplace(%p, %p)\n", new_locale, orig);
265 
266  _cs_locale_free_contents(new_locale);
267  if (orig->language) {
268  new_locale->language = strdup(orig->language);
269  if (!new_locale->language)
270  goto Cleanup;
271  }
272 
273  if (orig->charset) {
274  new_locale->charset = strdup(orig->charset);
275  if (!new_locale->charset)
276  goto Cleanup;
277  }
278 
279  if (orig->time) {
280  new_locale->time = strdup(orig->time);
281  if (!new_locale->time)
282  goto Cleanup;
283  }
284 
285  if (orig->collate) {
286  new_locale->collate = strdup(orig->collate);
287  if (!new_locale->collate)
288  goto Cleanup;
289  }
290 
291  return 1;
292 
293 Cleanup:
294  _cs_locale_free_contents(new_locale);
295  return 0;
296 }
297 
298 /* returns NULL on out of memory errors */
299 CS_LOCALE *
301 {
302  CS_LOCALE *new_locale;
303 
304  tdsdump_log(TDS_DBG_FUNC, "_cs_locale_copy(%p)\n", orig);
305 
306  new_locale = _cs_locale_alloc();
307  if (!new_locale)
308  return NULL;
309 
310  if (orig->language) {
311  new_locale->language = strdup(orig->language);
312  if (!new_locale->language)
313  goto Cleanup;
314  }
315 
316  if (orig->charset) {
317  new_locale->charset = strdup(orig->charset);
318  if (!new_locale->charset)
319  goto Cleanup;
320  }
321 
322  if (orig->time) {
323  new_locale->time = strdup(orig->time);
324  if (!new_locale->time)
325  goto Cleanup;
326  }
327 
328  if (orig->collate) {
329  new_locale->collate = strdup(orig->collate);
330  if (!new_locale->collate)
331  goto Cleanup;
332  }
333 
334  return new_locale;
335 
336 Cleanup:
337  _cs_locale_free(new_locale);
338  return NULL;
339 }
340 
343 {
344  TDSCONTEXT *tds_ctx;
345 
346  tdsdump_log(TDS_DBG_FUNC, "cs_ctx_alloc(%d, %p)\n", version, ctx);
347 
348  *ctx = tds_new0(CS_CONTEXT, 1);
349  tds_ctx = tds_alloc_context(*ctx);
350  if (!tds_ctx) {
351  free(*ctx);
352  return CS_FAIL;
353  }
354  (*ctx)->tds_ctx = tds_ctx;
355  if (tds_ctx->locale && !tds_ctx->locale->date_fmt) {
356  /* set default in case there's no locale file */
357  tds_ctx->locale->date_fmt = strdup(STD_DATETIME_FMT);
358  }
359 
360  (*ctx)->login_timeout = -1;
361  (*ctx)->query_timeout = -1;
362 
363  return CS_SUCCEED;
364 }
365 
368 {
369  static CS_CONTEXT *global_cs_ctx = NULL;
370 
371  tdsdump_log(TDS_DBG_FUNC, "cs_ctx_global(%d, %p)\n", version, ctx);
372 
373  if (global_cs_ctx != NULL) {
374  *ctx = global_cs_ctx;
375  return CS_SUCCEED;
376  }
377  if (cs_ctx_alloc(version, ctx) != CS_SUCCEED) {
378  return CS_FAIL;
379  }
380  global_cs_ctx = *ctx;
381  return CS_SUCCEED;
382 }
383 
386 {
387  tdsdump_log(TDS_DBG_FUNC, "cs_ctx_drop(%p)\n", ctx);
388 
389  if (ctx) {
391  free(ctx->userdata);
392  if (ctx->tds_ctx)
394  free(ctx);
395  }
396  return CS_SUCCEED;
397 }
398 
400 cs_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
401 {
402  CS_INT maxcp; /* declared for - CS_USERDATA changes - swapna*/
403 
404  tdsdump_log(TDS_DBG_FUNC, "cs_config(%p, %d, %d, %p, %d, %p)\n", ctx, action, property, buffer, buflen, outlen);
405 
406  if (action == CS_GET) {
407  if (buffer == NULL) {
408  return CS_SUCCEED;
409  }
410  switch (property) {
411  case CS_MESSAGE_CB:
412  *(void **) buffer = (void*) ctx->_cslibmsg_cb;
413  return CS_SUCCEED;
414  case CS_USERDATA:
415  maxcp = ctx->userdata_len;
416  if (outlen)
417  *outlen = maxcp;
418  if (maxcp > buflen)
419  maxcp = buflen;
420 
421  memcpy(buffer, ctx->userdata, maxcp);
422 
423  return CS_SUCCEED;
424  case CS_EXTRA_INF:
425  case CS_LOC_PROP:
426  case CS_VERSION:
427  return CS_FAIL;
428  break;
429  }
430  }
431  if (action == CS_SET) {
432  switch (property) {
433  case CS_MESSAGE_CB:
436  }
439  return CS_SUCCEED;
440  case CS_USERDATA:
441  free(ctx->userdata);
442 
443  if (buflen == CS_NULLTERM) {
444  maxcp = strlen((char*) buffer) + 1;
445  } else {
446  maxcp = buflen;
447  }
448  ctx->userdata = (void *) malloc(maxcp);
449  if ( ctx->userdata == NULL) {
450  return CS_FAIL;
451  }
452  ctx->userdata_len = maxcp;
453 
454  if (buffer) {
455  memcpy(ctx->userdata, buffer, maxcp);
456  } else {
457  return CS_FAIL;
458  }
459  return CS_SUCCEED;
460 
461  case CS_EXTRA_INF:
462  case CS_LOC_PROP:
463  case CS_VERSION:
464  return CS_FAIL;
465  break;
466  }
467  }
468  if (action == CS_CLEAR) {
469  switch (property) {
470  case CS_MESSAGE_CB:
473  }
474  ctx->_cslibmsg_cb = NULL;
475  ctx->cs_errhandletype = 0;
476  return CS_SUCCEED;
477  case CS_USERDATA:
478  free(ctx->userdata);
479  ctx->userdata = NULL;
480 
481  return CS_SUCCEED;
482 
483  case CS_EXTRA_INF:
484  case CS_LOC_PROP:
485  case CS_VERSION:
486  return CS_FAIL;
487  break;
488  }
489  }
490  return CS_FAIL;
491 }
492 
494 cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT * destfmt, CS_VOID * destdata, CS_INT * resultlen)
495 {
496  return _cs_convert_ex(ctx, srcfmt, srcdata, destfmt, destdata,
497  resultlen, TDS_INVALID_TYPE, NULL);
498 }
499 
502  CS_DATAFMT * destfmt, CS_VOID * destdata, CS_INT * resultlen,
503  TDS_SERVER_TYPE desttype, CS_VOID ** handle)
504 {
505  TDS_SERVER_TYPE src_type;
506  int src_len, destlen, len, i = 0;
507  CONV_RESULT cres;
508  unsigned char *dest;
509  CS_RETCODE ret;
510  CS_INT dummy;
511  CS_VARCHAR *destvc = NULL;
512 
513  tdsdump_log(TDS_DBG_FUNC, "cs_convert(%p, %p, %p, %p, %p, %p)\n", ctx, srcfmt, srcdata, destfmt, destdata, resultlen);
514 
515  /* If destination is NULL we have a problem */
516  if (destdata == NULL) {
517  /* TODO: add error message */
518  tdsdump_log(TDS_DBG_FUNC, "error: destdata is null\n");
519  return CS_FAIL;
520 
521  }
522 
523  /* If destfmt is NULL we have a problem */
524  if (destfmt == NULL) {
525  /* TODO: add error message */
526  tdsdump_log(TDS_DBG_FUNC, "error: destfmt is null\n");
527  return CS_FAIL;
528 
529  }
530 
531  if (resultlen == NULL)
532  resultlen = &dummy;
533 
534  /* If source is indicated to be NULL, set dest to low values */
535  if (srcdata == NULL) {
536  /* TODO: implement cs_setnull */
537  tdsdump_log(TDS_DBG_FUNC, "srcdata is null\n");
538  memset(destdata, '\0', destfmt->maxlength);
539  *resultlen = 0;
540  return CS_SUCCEED;
541 
542  }
543 
544  src_type = _ct_get_server_type(NULL, srcfmt->datatype);
545  if (src_type == TDS_INVALID_TYPE)
546  return CS_FAIL;
547  src_len = srcfmt->maxlength;
548  if (srcfmt->datatype == CS_VARCHAR_TYPE ||
549  srcfmt->datatype == CS_NVARCHAR_TYPE ||
550  srcfmt->datatype == CS_VARBINARY_TYPE) {
551  CS_VARCHAR *vc = (CS_VARCHAR *) srcdata;
552  src_len = vc->len;
553  srcdata = vc->str;
554  }
555  if (desttype == TDS_INVALID_TYPE) {
556  desttype = _ct_get_server_type(NULL, destfmt->datatype);
557  if (desttype == TDS_INVALID_TYPE) {
558  return CS_FAIL;
559  }
560  }
561  destlen = destfmt->maxlength;
562  if (destfmt->datatype == CS_VARCHAR_TYPE ||
563  destfmt->datatype == CS_NVARCHAR_TYPE ||
564  destfmt->datatype == CS_VARBINARY_TYPE) {
565  destvc = (CS_VARCHAR *) destdata;
566  destlen = sizeof(destvc->str);
567  destdata = destvc->str;
568  } else if (is_numeric_type(desttype)) {
569  destlen = sizeof(TDS_NUMERIC);
570  }
571 
572  tdsdump_log(TDS_DBG_FUNC, "converting type %d (%d bytes) to type = %d (%d bytes)\n",
573  src_type, src_len, desttype, destlen);
574 
575  if (!is_fixed_type(desttype) && (destlen < 0)) { /* was <= */
576  return CS_FAIL;
577  }
578 
579  dest = (unsigned char *) destdata;
580 
581  /* many times we are asked to convert a data type to itself */
582 
583  if (src_type == desttype) {
584  int minlen = src_len < destlen? src_len : destlen;
585 
586  tdsdump_log(TDS_DBG_FUNC, "cs_convert() srctype == desttype\n");
587  switch (desttype) {
588 
589  case SYBLONGBINARY:
590  case SYBBINARY:
591  case SYBVARBINARY:
592  case SYBIMAGE:
593  memcpy(dest, srcdata, minlen);
594  *resultlen = minlen;
595 
596  if (src_len > destlen) {
597  tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
598  _csclient_msg(ctx, "cs_convert", 2, 1, 16, 26,
599  "");
600  ret = CS_FAIL;
601  } else {
602  switch (destfmt->format) {
603  case CS_FMT_PADNULL:
604  memset(dest + src_len, '\0', destlen - src_len);
605  *resultlen = destlen;
606  /* fall through */
607  case CS_FMT_UNUSED:
608  ret = CS_SUCCEED;
609  break;
610  default:
611  ret = CS_FAIL;
612  break;
613  }
614  }
615  if (destvc) {
616  destvc->len = minlen;
617  *resultlen = sizeof(*destvc);
618  }
619  break;
620 
621  case SYBCHAR:
622  case SYBVARCHAR:
623  case SYBTEXT:
624  case SYBNVARCHAR:
625  case SYBNTEXT:
626  tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n");
627 
628  memcpy(dest, srcdata, minlen);
629  *resultlen = minlen;
630 
631  if (src_len > destlen) {
632  tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
633  _csclient_msg(ctx, "cs_convert", 2, 1, 10, 25,
634  "");
635  src_len = destlen;
636  } /* else */ {
637  switch (destfmt->format) {
638  case CS_FMT_NULLTERM:
639  if (src_len == destlen) {
640  *resultlen = src_len;
641  tdsdump_log(TDS_DBG_FUNC, "error: no room for null terminator\n");
642  ret = CS_FAIL;
643  } else {
644  dest[src_len] = '\0';
645  *resultlen = src_len + 1;
646  ret = CS_SUCCEED;
647  }
648  break;
649 
650  case CS_FMT_PADBLANK:
651  memset(dest + src_len, ' ', destlen - src_len);
652  *resultlen = destlen;
653  ret = CS_SUCCEED;
654  break;
655  case CS_FMT_PADNULL:
656  memset(dest + src_len, '\0', destlen - src_len);
657  *resultlen = destlen;
658  ret = CS_SUCCEED;
659  break;
660  case CS_FMT_UNUSED:
661  ret = CS_SUCCEED;
662  break;
663  default:
664  tdsdump_log(TDS_DBG_FUNC, "no destination format specified!\n");
665  ret = CS_FAIL;
666  break;
667  }
668  }
669  if (destvc) {
670  destvc->len = minlen;
671  *resultlen = sizeof(*destvc);
672  }
673  break;
674  case SYBINT1:
675  case SYBUINT1:
676  case SYBINT2:
677  case SYBUINT2:
678  case SYBINT4:
679  case SYBUINT4:
680  case SYBINT8:
681  case SYBUINT8:
682  case SYBFLT8:
683  case SYBREAL:
684  case SYBBIT:
685  case SYBMONEY:
686  case SYBMONEY4:
687  case SYBDATETIME:
688  case SYBDATETIME4:
689  case SYBTIME:
690  case SYBDATE:
691  case SYB5BIGDATETIME:
692  case SYB5BIGTIME:
693  *resultlen = tds_get_size_by_type(src_type);
694  if (*resultlen > 0)
695  memcpy(dest, srcdata, *resultlen);
696  ret = CS_SUCCEED;
697  break;
698 
699  case SYBNUMERIC:
700  case SYBDECIMAL:
701  src_len = tds_numeric_bytes_per_prec[((TDS_NUMERIC *) srcdata)->precision] + 2;
702  case SYBBITN:
703  case SYBUNIQUE:
704  memcpy(dest, srcdata, minlen);
705  *resultlen = minlen;
706 
707  if (src_len > destlen) {
708  tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
709  _csclient_msg(ctx, "cs_convert", 2, 1, 16, 26,
710  "");
711  ret = CS_FAIL;
712  } else {
713  ret = CS_SUCCEED;
714  }
715  break;
716 
717  default:
718  tdsdump_log(TDS_DBG_FUNC, "error: unrecognized type\n");
719  ret = CS_FAIL;
720  break;
721  }
722 
723  tdsdump_log(TDS_DBG_FUNC, "cs_convert() returning %s\n", cs_prretcode(ret));
724  return ret;
725 
726  }
727 
728  assert(src_type != desttype);
729 
730  /* set the output precision/scale for conversions to numeric type */
731  if (is_numeric_type(desttype)) {
732  cres.n.precision = destfmt->precision;
733  cres.n.scale = destfmt->scale;
734  if (destfmt->precision == CS_SRC_VALUE)
735  cres.n.precision = srcfmt->precision;
736  if (destfmt->scale == CS_SRC_VALUE)
737  cres.n.scale = srcfmt->scale;
738  }
739 
740  tdsdump_log(TDS_DBG_FUNC, "cs_convert() calling tds_convert\n");
741  len = tds_convert(ctx->tds_ctx, src_type, (TDS_CHAR*) srcdata, src_len, desttype, &cres);
742 
743  tdsdump_log(TDS_DBG_FUNC, "cs_convert() tds_convert returned %d\n", len);
744 
745  switch (len) {
746  case TDS_CONVERT_NOAVAIL:
747  _csclient_msg(ctx, "cs_convert", 2, 1, 1, 16, "%d, %d", src_type, desttype);
748  return CS_FAIL;
749  break;
750  case TDS_CONVERT_SYNTAX:
751  _csclient_msg(ctx, "cs_convert", 2, 4, 1, 24, "");
752  return CS_FAIL;
753  break;
754  case TDS_CONVERT_NOMEM:
755  _csclient_msg(ctx, "cs_convert", 2, 4, 1, 3, "");
756  return CS_FAIL;
757  break;
759  _csclient_msg(ctx, "cs_convert", 2, 4, 1, 20, "");
760  return CS_FAIL;
761  break;
762  case TDS_CONVERT_FAIL:
763  return CS_FAIL;
764  break;
765  default:
766  if (len < 0) {
767  return CS_FAIL;
768  }
769  break;
770  }
771 
772  switch (desttype) {
773  case SYBBINARY:
774  case SYBVARBINARY:
775  case SYBIMAGE:
776  ret = CS_SUCCEED;
777  if (len > destlen) {
778  tdsdump_log(TDS_DBG_FUNC, "error_handler: Data-conversion resulted in overflow\n");
779  _csclient_msg(ctx, "cs_convert", 2, 1, 16, 26, "");
780  ret = CS_FAIL;
781  len = destlen;
782  }
783  if (handle == NULL) {
784  memcpy(dest, cres.ib, len);
785  free(cres.ib);
786  } else {
787  free(*handle);
788  *handle = cres.ib;
789  destlen = len;
790  }
791  *resultlen = len;
792  if (destvc) {
793  destvc->len = len;
794  *resultlen = sizeof(*destvc);
795  }
796  for (i = len; i < destlen; i++)
797  dest[i] = '\0';
798  break;
799  case SYBBIT:
800  case SYBBITN:
801  /* fall trough, act same way of TINYINT */
802  case SYBINT1:
803  case SYBUINT1:
804  case SYBINT2:
805  case SYBUINT2:
806  case SYBINT4:
807  case SYBUINT4:
808  case SYBINT8:
809  case SYBUINT8:
810  case SYBFLT8:
811  case SYBREAL:
812  case SYBMONEY:
813  case SYBMONEY4:
814  case SYBDATETIME:
815  case SYBDATETIME4:
816  case SYBTIME:
817  case SYBDATE:
818  case SYBUNIQUE:
819  case SYB5BIGDATETIME:
820  case SYB5BIGTIME:
821  *resultlen = tds_get_size_by_type(desttype);
822  memcpy(dest, &(cres.ti), *resultlen);
823  ret = CS_SUCCEED;
824  break;
825  case SYBNUMERIC:
826  case SYBDECIMAL:
827  src_len = tds_numeric_bytes_per_prec[cres.n.precision] + 2;
828  memcpy(dest, &(cres.n), src_len);
829  *resultlen = src_len;
830  ret = CS_SUCCEED;
831  break;
832  case SYBMSTIME:
833  case SYBMSDATE:
834  case SYBMSDATETIME2:
835  case SYBMSDATETIMEOFFSET:
836  *resultlen = sizeof(TDS_DATETIMEALL);
837  memcpy(dest, &(cres.dta), *resultlen);
838  ret = CS_SUCCEED;
839  break;
840  case SYBCHAR:
841  case SYBVARCHAR:
842  case SYBTEXT:
843  case SYBNVARCHAR:
844  case SYBNTEXT:
845  ret = CS_SUCCEED;
846  if (len > destlen) {
847  tdsdump_log(TDS_DBG_FUNC, "Data-conversion resulted in overflow\n");
848  _csclient_msg(ctx, "cs_convert", 2, 1, 10, 25, "");
849  len = destlen;
850  }
851  switch (destfmt->format) {
852 
853  case CS_FMT_NULLTERM:
854  tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n");
855  if (len == destlen) {
856  tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n");
857  ret = CS_FAIL; /* not enough room for data + a null terminator - error */
858  } else {
859  if (handle == NULL) {
860  memcpy(dest, cres.c, len);
861  } else {
862  free(*handle);
863  *handle = cres.c;
864  dest = *handle;
865  }
866  dest[len] = 0;
867  *resultlen = len + 1;
868  }
869  break;
870 
871  case CS_FMT_PADBLANK:
872  tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADBLANK\n");
873  /* strcpy here can lead to a small buffer overflow */
874  if (handle == NULL) {
875  memcpy(dest, cres.c, len);
876  } else {
877  free(*handle);
878  *handle = cres.c;
879  destlen = len;
880  }
881  for (i = len; i < destlen; i++)
882  dest[i] = ' ';
883  *resultlen = destlen;
884  break;
885 
886  case CS_FMT_PADNULL:
887  tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADNULL\n");
888  /* strcpy here can lead to a small buffer overflow */
889  if (handle == NULL) {
890  memcpy(dest, cres.c, len);
891  } else {
892  free(*handle);
893  *handle = cres.c;
894  destlen = len;
895  }
896  for (i = len; i < destlen; i++)
897  dest[i] = '\0';
898  *resultlen = destlen;
899  break;
900  case CS_FMT_UNUSED:
901  tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_UNUSED\n");
902  if (handle == NULL) {
903  memcpy(dest, cres.c, len);
904  } else {
905  free(*handle);
906  *handle = cres.c;
907  }
908  *resultlen = len;
909  break;
910  default:
911  ret = CS_FAIL;
912  break;
913  }
914  if (destvc) {
915  destvc->len = len;
916  *resultlen = sizeof(*destvc);
917  }
918  if (handle == NULL || *handle != cres.c) {
919  free(cres.c);
920  }
921  break;
922  default:
923  ret = CS_FAIL;
924  break;
925  }
926  tdsdump_log(TDS_DBG_FUNC, "cs_convert() returning %s\n", cs_prretcode(ret));
927  return (ret);
928 }
929 
931 cs_dt_crack_v2(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * daterec)
932 {
933  TDSDATEREC dr;
934  TDS_INT tds_type;
935  bool extended = false;
936 
937  tdsdump_log(TDS_DBG_FUNC, "cs_dt_crack_v2(%p, %d, %p, %p)\n", ctx, datetype, dateval, daterec);
938 
939  switch (datetype) {
940  case CS_DATETIME_TYPE:
941  tds_type = SYBDATETIME;
942  break;
943  case CS_DATETIME4_TYPE:
944  tds_type = SYBDATETIME4;
945  break;
946  case CS_DATE_TYPE:
947  tds_type = SYBDATE;
948  break;
949  case CS_TIME_TYPE:
950  tds_type = SYBTIME;
951  break;
952  case CS_BIGDATETIME_TYPE:
953  tds_type = SYB5BIGDATETIME;
954  extended = true;
955  break;
956  case CS_BIGTIME_TYPE:
957  tds_type = SYB5BIGTIME;
958  extended = true;
959  break;
960  default:
961  return CS_FAIL;
962  }
963  tds_datecrack(tds_type, dateval, &dr);
964 
965  /* Sybase CT-Library does not set these fields for CS_BIGTIME_TYPE */
966  if (tds_type != SYB5BIGTIME) {
967  daterec->dateyear = dr.year;
968  daterec->datemonth = dr.month;
969  daterec->datedmonth = dr.day;
970  daterec->datedyear = dr.dayofyear;
971  daterec->datedweek = dr.weekday;
972  }
973  daterec->datehour = dr.hour;
974  daterec->dateminute = dr.minute;
975  daterec->datesecond = dr.second;
976  daterec->datemsecond = dr.decimicrosecond / 10000u;
977  daterec->datetzone = dr.timezone;
978  if (extended) {
979  daterec->datesecfrac = dr.decimicrosecond / 10u;
980  daterec->datesecprec = 1000000;
981  }
982 
983  return CS_SUCCEED;
984 }
985 
987 cs_dt_crack(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * daterec)
988 {
989  tdsdump_log(TDS_DBG_FUNC, "cs_dt_crack(%p, %d, %p, %p)\n", ctx, datetype, dateval, daterec);
990 
991  if (datetype != CS_BIGDATETIME_TYPE && datetype != CS_BIGTIME_TYPE)
992  return cs_dt_crack_v2(ctx, datetype, dateval, daterec);
993  return CS_FAIL;
994 }
995 
998 {
999  CS_LOCALE *tds_csloc;
1000 
1001  tdsdump_log(TDS_DBG_FUNC, "cs_loc_alloc(%p, %p)\n", ctx, locptr);
1002 
1003  tds_csloc = _cs_locale_alloc();
1004  if (!tds_csloc)
1005  return CS_FAIL;
1006 
1007  *locptr = tds_csloc;
1008  return CS_SUCCEED;
1009 }
1010 
1011 CS_RETCODE
1013 {
1014  tdsdump_log(TDS_DBG_FUNC, "cs_loc_drop(%p, %p)\n", ctx, locale);
1015 
1016  if (!locale)
1017  return CS_FAIL;
1018 
1020  return CS_SUCCEED;
1021 }
1022 
1023 CS_RETCODE
1025 {
1027 
1028  tdsdump_log(TDS_DBG_FUNC, "cs_locale(%p, %d, %p, %d, %p, %d, %p)\n", ctx, action, locale, type, buffer, buflen, outlen);
1029 
1030  if (action == CS_SET) {
1031  switch (type) {
1032  case CS_LC_ALL:
1033  /* what to do here if there is locale data? */
1034  if (!buffer) {
1035  code = CS_SUCCEED;
1036  }
1037  break;
1038 
1039  case CS_SYB_CHARSET:
1040  if (buflen == CS_NULLTERM) {
1041  buflen = (int)strlen((char *)buffer);
1042  }
1043 
1044  free(locale->charset);
1045  locale->charset = tds_strndup(buffer, buflen);
1046  if (!locale->charset)
1047  break;
1048 
1049  code = CS_SUCCEED;
1050  break;
1051 
1052  case CS_SYB_LANG:
1053  if (buflen == CS_NULLTERM) {
1054  buflen = (int)strlen((char *)buffer);
1055  }
1056 
1057  free(locale->language);
1058  locale->language = tds_strndup(buffer, buflen);
1059  if (!locale->language)
1060  break;
1061 
1062  code = CS_SUCCEED;
1063  break;
1064 
1065  case CS_SYB_LANG_CHARSET:
1066  {
1067  int i;
1068  char *b = (char *)buffer;
1069 
1070  if (buflen == CS_NULLTERM) {
1071  buflen = (int)strlen(b);
1072  }
1073 
1074  /* find '.' character */
1075  for (i = 0; i < buflen; ++i) {
1076  if (b[i] == '.') {
1077  break;
1078  }
1079  }
1080  /* not found */
1081  if (i == buflen) {
1082  break;
1083  }
1084  if (i) {
1085  free(locale->language);
1086  locale->language = tds_strndup(b, i);
1087  if (!locale->language)
1088  break;
1089  }
1090  if (i != (buflen - 1)) {
1091  free(locale->charset);
1092  locale->charset = tds_strndup(b + i + 1, buflen - i - 1);
1093  if (!locale->charset)
1094  break;
1095  }
1096  code = CS_SUCCEED;
1097  break;
1098  }
1099 
1100  /* TODO commented out until the code works end-to-end
1101  case CS_SYB_SORTORDER:
1102  if (buflen == CS_NULLTERM) {
1103  buflen = strlen((char *)buffer);
1104  }
1105 
1106  free(locale->collate);
1107  locale->collate = tds_strndup(buffer, buflen);
1108  if (!locale->collate)
1109  break;
1110 
1111  code = CS_SUCCEED;
1112  break;
1113  */
1114  }
1115  }
1116  else if (action == CS_GET)
1117  {
1118  int tlen;
1119 
1120  switch (type) {
1121  case CS_SYB_CHARSET:
1122  tlen = (locale->charset ? (int)strlen(locale->charset)
1123  : 0) + 1;
1124  if (buflen < tlen)
1125  {
1126  if (outlen)
1127  *outlen = tlen;
1128  break;
1129  }
1130  if (locale->charset)
1131  strcpy((char *)buffer, locale->charset);
1132  else
1133  ((char *)buffer)[0] = '\0';
1134  code = CS_SUCCEED;
1135  break;
1136 
1137  case CS_SYB_LANG:
1138  tlen = (locale->language ?
1139  (int)strlen(locale->language) : 0) + 1;
1140  if (buflen < tlen)
1141  {
1142  if (outlen)
1143  *outlen = tlen;
1144  break;
1145  }
1146  if (locale->language)
1147  strcpy((char *)buffer, locale->language);
1148  else
1149  ((char *)buffer)[0] = '\0';
1150  code = CS_SUCCEED;
1151  break;
1152 
1153  case CS_SYB_LANG_CHARSET:
1154  {
1155  int clen;
1156 
1157  tlen = (locale->language ?
1158  (int)strlen(locale->language) : 0) + 1;
1159  clen = (locale->charset ?
1160  (int)strlen(locale->charset) : 0) + 1;
1161 
1162  if (buflen < (tlen + clen))
1163  {
1164  if (outlen)
1165  *outlen = tlen + clen;
1166  break;
1167  }
1168  if (locale->language)
1169  strcpy((char *)buffer, locale->language);
1170  else
1171  ((char *)buffer)[0] = '\0';
1172  strcat((char *)buffer, ".");
1173  if (locale->charset) {
1174  tlen = (int)strlen((char *)buffer);
1175  strcpy((char *)buffer + tlen, locale->charset);
1176  }
1177  code = CS_SUCCEED;
1178  break;
1179  }
1180 
1181  case CS_SYB_SORTORDER:
1182  tlen = (locale->collate ? (int)strlen(locale->collate)
1183  : 0) + 1;
1184  if (buflen < tlen)
1185  {
1186  if (outlen)
1187  *outlen = tlen;
1188  break;
1189  }
1190  if (locale->collate)
1191  strcpy((char *)buffer, locale->collate);
1192  else
1193  ((char *)buffer)[0] = '\0';
1194  code = CS_SUCCEED;
1195  break;
1196  }
1197  }
1198  return code;
1199 }
1200 
1201 CS_RETCODE
1203  CS_INT * outlen)
1204 {
1205  tdsdump_log(TDS_DBG_FUNC, "cs_dt_info(%p, %d, %p, %d, %d, %p, %d, %p)\n",
1206  ctx, action, locale, type, item, buffer, buflen, outlen);
1207 
1208  if (action == CS_SET) {
1209  switch (type) {
1210  case CS_DT_CONVFMT:
1211  break;
1212  }
1213  }
1214  return CS_SUCCEED;
1215 }
1216 
1217 CS_RETCODE
1218 cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultlen, CS_CHAR * text, CS_INT textlen,
1219  CS_CHAR * formats, CS_INT formatlen, ...)
1220 {
1221  va_list ap;
1222  TDSRET rc;
1223 
1224  tdsdump_log(TDS_DBG_FUNC, "cs_strbuild(%p, %p, %d, %p, %p, %d, %p, %d)\n",
1225  ctx, buffer, buflen, resultlen, text, textlen, formats, formatlen);
1226 
1227  va_start(ap, formatlen);
1228  rc = tds_vstrbuild(buffer, buflen, resultlen, text, textlen, formats, formatlen, ap);
1229  va_end(ap);
1230 
1231  return TDS_SUCCEED(rc) ? CS_SUCCEED : CS_FAIL;
1232 }
1233 
1234 CS_RETCODE
1235 cs_calc(CS_CONTEXT * ctx, CS_INT op, CS_INT datatype, CS_VOID * var1, CS_VOID * var2, CS_VOID * dest)
1236 {
1237 
1238  tdsdump_log(TDS_DBG_FUNC, "cs_calc(%p, %d, %d, %p, %p, %p)\n", ctx, op, datatype, var1, var2, dest);
1239 
1240  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_calc()\n");
1241  return CS_FAIL;
1242 }
1243 
1244 CS_RETCODE
1245 cs_cmp(CS_CONTEXT * ctx, CS_INT datatype, CS_VOID * var1, CS_VOID * var2, CS_INT * result)
1246 {
1247 
1248  tdsdump_log(TDS_DBG_FUNC, "cs_cmp(%p, %d, %p, %p, %p)\n", ctx, datatype, var1, var2, result);
1249 
1250  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_cmp()\n");
1251  return CS_FAIL;
1252 }
1253 
1254 CS_RETCODE
1255 cs_conv_mult(CS_CONTEXT * ctx, CS_LOCALE * srcloc, CS_LOCALE * destloc, CS_INT * conv_multiplier)
1256 {
1257 
1258  tdsdump_log(TDS_DBG_FUNC, "cs_conv_mult(%p, %p, %p, %p)\n", ctx, srcloc, destloc, conv_multiplier);
1259 
1260  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_conv_mult()\n");
1261  return CS_FAIL;
1262 }
1263 
1264 CS_RETCODE
1266 {
1267  tdsdump_log(TDS_DBG_FUNC, "cs_diag(%p, %d, %d, %d, %p)\n", ctx, operation, type, idx, buffer);
1268 
1269  switch (operation) {
1270 
1271  case CS_INIT:
1272  if ( ctx->cs_errhandletype == _CS_ERRHAND_CB) {
1273  /* contrary to the manual page you don't seem to */
1274  /* be able to turn on inline message handling */
1275  /* using cs_diag, once a callback is installed! */
1276  return CS_FAIL;
1277  }
1281  break;
1282  case CS_MSGLIMIT:
1284  return CS_FAIL;
1285  }
1287  break;
1288  case CS_CLEAR:
1290  return CS_FAIL;
1291  }
1292  return (cs_diag_clearmsg(ctx, type));
1293 
1294  break;
1295  case CS_GET:
1297  return CS_FAIL;
1298  }
1299  if (buffer == NULL)
1300  return CS_FAIL;
1301 
1302  if (idx == 0 || (ctx->cs_diag_msglimit != CS_NO_LIMIT && idx > ctx->cs_diag_msglimit) )
1303  return CS_FAIL;
1304 
1305  return (cs_diag_getmsg(ctx, idx, (CS_CLIENTMSG *)buffer));
1306 
1307  break;
1308  case CS_STATUS:
1310  return CS_FAIL;
1311  }
1312  if (buffer == NULL)
1313  return CS_FAIL;
1314 
1315  return (cs_diag_countmsg(ctx, (CS_INT *)buffer));
1316  break;
1317  }
1318  return CS_SUCCEED;
1319 
1320 }
1321 
1322 CS_RETCODE
1323 cs_manage_convert(CS_CONTEXT * ctx, CS_INT action, CS_INT srctype, CS_CHAR * srcname, CS_INT srcnamelen, CS_INT desttype,
1324  CS_CHAR * destname, CS_INT destnamelen, CS_INT * conv_multiplier, CS_CONV_FUNC * func)
1325 {
1326 
1327  tdsdump_log(TDS_DBG_FUNC, "cs_manage_convert(%p, %d, %d, %p, %d, %d, %p, %d, %p, %p)\n",
1328  ctx, action, srctype, srcname, srcnamelen, desttype, destname, destnamelen, conv_multiplier, func);
1329 
1330  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_manage_convert()\n");
1331  return CS_FAIL;
1332 }
1333 
1334 CS_RETCODE
1335 cs_objects(CS_CONTEXT * ctx, CS_INT action, CS_OBJNAME * objname, CS_OBJDATA * objdata)
1336 {
1337 
1338  tdsdump_log(TDS_DBG_FUNC, "cs_objects(%p, %d, %p, %p)\n", ctx, action, objname, objdata);
1339 
1340  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_objects()\n");
1341  return CS_FAIL;
1342 }
1343 
1344 CS_RETCODE
1345 cs_set_convert(CS_CONTEXT * ctx, CS_INT action, CS_INT srctype, CS_INT desttype, CS_CONV_FUNC * func)
1346 {
1347 
1348  tdsdump_log(TDS_DBG_FUNC, "cs_set_convert(%p, %d, %d, %d, %p)\n", ctx, action, srctype, desttype, func);
1349 
1350  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_set_convert()\n");
1351  return CS_FAIL;
1352 }
1353 
1354 CS_RETCODE
1356 {
1357 
1358  tdsdump_log(TDS_DBG_FUNC, "cs_setnull(%p, %p, %p, %d)\n", ctx, datafmt, buffer, buflen);
1359 
1360  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_setnull()\n");
1361  return CS_FAIL;
1362 }
1363 
1364 CS_RETCODE
1366  CS_INT * result)
1367 {
1368 
1369  tdsdump_log(TDS_DBG_FUNC, "cs_strcmp(%p, %p, %d, %p, %d, %p, %d, %p)\n",
1370  ctx, locale, type, str1, len1, str2, len2, result);
1371 
1372  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_strcmp()\n");
1373  return CS_FAIL;
1374 }
1375 
1376 CS_RETCODE
1378 {
1379 
1380  tdsdump_log(TDS_DBG_FUNC, "cs_time(%p, %p, %p, %d, %p, %p)\n", ctx, locale, buffer, buflen, outlen, daterec);
1381 
1382  tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_time()\n");
1383  return CS_FAIL;
1384 }
1385 
1386 CS_RETCODE
1388 {
1389 
1390  tdsdump_log(TDS_DBG_FUNC, "cs_will_convert(%p, %d, %d, %p)\n", ctx, srctype, desttype, result);
1391 
1392  *result = (tds_willconvert(srctype, desttype) ? CS_TRUE : CS_FALSE);
1393  return CS_SUCCEED;
1394 }
1395 
1396 static CS_INT
1398 {
1399  struct cs_diag_msg **curptr;
1400  CS_INT msg_count = 0;
1401 
1402  tdsdump_log(TDS_DBG_FUNC, "cs_diag_storemsg(%p, %p)\n", context, message);
1403 
1404  curptr = &(context->msgstore);
1405 
1406  /* if we already have a list of messages, */
1407  /* go to the end of the list... */
1408 
1409  while (*curptr != NULL) {
1410  msg_count++;
1411  curptr = &((*curptr)->next);
1412  }
1413 
1414  /* messages over and above the agreed limit */
1415  /* are simply discarded... */
1416 
1418  msg_count >= context->cs_diag_msglimit) {
1419  return CS_FAIL;
1420  }
1421 
1422  *curptr = tds_new(struct cs_diag_msg, 1);
1423  if (*curptr == NULL) {
1424  return CS_FAIL;
1425  } else {
1426  (*curptr)->next = NULL;
1427  (*curptr)->msg = tds_new(CS_CLIENTMSG, 1);
1428  if ((*curptr)->msg == NULL) {
1429  return CS_FAIL;
1430  } else {
1431  memcpy((*curptr)->msg, message, sizeof(CS_CLIENTMSG));
1432  }
1433  }
1434 
1435  return CS_SUCCEED;
1436 }
1437 
1438 static CS_INT
1440 {
1441  struct cs_diag_msg *curptr;
1442  CS_INT msg_count = 0, msg_found = 0;
1443 
1444  tdsdump_log(TDS_DBG_FUNC, "cs_diag_getmsg(%p, %d, %p)\n", context, idx, message);
1445 
1446  curptr = context->msgstore;
1447 
1448  /* if we already have a list of messages, */
1449  /* go to the end of the list... */
1450 
1451  while (curptr != NULL) {
1452  msg_count++;
1453  if (msg_count == idx) {
1454  msg_found++;
1455  break;
1456  }
1457  curptr = curptr->next;
1458  }
1459  if (msg_found) {
1460  memcpy(message, curptr->msg, sizeof(CS_CLIENTMSG));
1461  return CS_SUCCEED;
1462  } else {
1463  return CS_NOMSG;
1464  }
1465 }
1466 
1467 static CS_INT
1469 {
1470  struct cs_diag_msg *curptr, *freeptr;
1471 
1472  tdsdump_log(TDS_DBG_FUNC, "cs_diag_clearmsg(%p, %d)\n", context, type);
1473 
1474  curptr = context->msgstore;
1475  context->msgstore = NULL;
1476 
1477  while (curptr != NULL ) {
1478  freeptr = curptr;
1479  curptr = freeptr->next;
1480  free(freeptr->msg);
1481  free(freeptr);
1482  }
1483  return CS_SUCCEED;
1484 }
1485 
1486 static CS_INT
1488 {
1489  struct cs_diag_msg *curptr;
1490  CS_INT msg_count = 0;
1491 
1492  tdsdump_log(TDS_DBG_FUNC, "cs_diag_countmsg(%p, %p)\n", context, count);
1493 
1494  curptr = context->msgstore;
1495 
1496  while (curptr != NULL) {
1497  msg_count++;
1498  curptr = curptr->next;
1499  }
1500  *count = msg_count;
1501  return CS_SUCCEED;
1502 }
1503 
1504 /**
1505  * Try to convert to a type we can handle
1506  */
1507 int
1508 _cs_convert_not_client(CS_CONTEXT *ctx, TDSCOLUMN *curcol, CONV_RESULT *convert_buffer, unsigned char **p_src)
1509 {
1510  int ct_type;
1511  TDS_SERVER_TYPE desttype;
1512 
1513  switch (curcol->column_type) {
1514  case SYBMSDATE:
1515  desttype = SYBDATE;
1516  ct_type = CS_DATE_TYPE;
1517  break;
1518  case SYBMSTIME:
1519  desttype = SYB5BIGTIME;
1520  ct_type = CS_BIGTIME_TYPE;
1521  break;
1522  case SYBMSDATETIME2:
1523  case SYBMSDATETIMEOFFSET:
1524  desttype = SYB5BIGDATETIME;
1525  ct_type = CS_BIGDATETIME_TYPE;
1526  break;
1527  default:
1528  return CS_ILLEGAL_TYPE;
1529  }
1530 
1531  if (convert_buffer) {
1532  int len = tds_convert(ctx->tds_ctx, curcol->column_type, (TDS_CHAR *) *p_src,
1533  curcol->column_cur_size, desttype, convert_buffer);
1534  if (len < 0)
1535  return CS_ILLEGAL_TYPE; // TODO _csclient_msg ??
1536  *p_src = (unsigned char *) convert_buffer;
1537  }
1538  return ct_type;
1539 }
unsigned dummy
Definition: block_cipher.h:0
#define CS_CANCELED
Definition: cspublic.h:53
#define CS_SRC_VALUE
Definition: cspublic.h:75
#define CS_VERSION
Definition: cspublic.h:208
#define CS_DT_CONVFMT
Definition: cspublic.h:607
#define CS_FAIL
Definition: cspublic.h:41
#define CS_PENDING
Definition: cspublic.h:43
#define CS_FMT_UNUSED
Definition: cspublic.h:398
#define CS_DATETIME4_TYPE
Definition: cspublic.h:563
#define CS_TIMED_OUT
Definition: cspublic.h:59
#define CS_BIGTIME_TYPE
Definition: cspublic.h:586
#define CS_TIME_TYPE
Definition: cspublic.h:578
#define CS_FMT_PADBLANK
Definition: cspublic.h:402
#define CS_DATE_TYPE
Definition: cspublic.h:577
#define CS_END_ITEM
Definition: cspublic.h:57
#define CS_INTERRUPT
Definition: cspublic.h:46
#define CS_FMT_PADNULL
Definition: cspublic.h:404
#define CS_BUSY
Definition: cspublic.h:45
#define CS_LOC_PROP
Definition: cspublic.h:226
#define CS_MSGLIMIT
Definition: cspublic.h:433
#define CS_FALSE
Definition: cspublic.h:721
#define CS_EXTRA_INF
Definition: cspublic.h:220
#define CS_SYB_CHARSET
Definition: cspublic.h:510
#define CS_BIGDATETIME_TYPE
Definition: cspublic.h:585
#define CS_DATETIME_TYPE
Definition: cspublic.h:562
#define CS_SYB_SORTORDER
Definition: cspublic.h:511
#define CS_MESSAGE_CB
Definition: cspublic.h:419
#define CS_USERDATA
Definition: cspublic.h:200
#define CS_UNUSED
Definition: cspublic.h:425
#define CS_END_DATA
Definition: cspublic.h:55
#define CS_MEM_ERROR
Definition: cspublic.h:42
#define CS_VARCHAR_TYPE
Definition: cspublic.h:568
#define CS_SET
Definition: cspublic.h:429
#define CS_SYB_LANG
Definition: cspublic.h:509
#define CS_INIT
Definition: cspublic.h:431
#define CS_TRUE
Definition: cspublic.h:722
#define CS_LC_ALL
Definition: cspublic.h:508
#define CS_NO_LIMIT
Definition: cspublic.h:424
#define CS_UNSUPPORTED
Definition: cspublic.h:51
#define CS_ROW_FAIL
Definition: cspublic.h:54
CS_RETCODE(* CS_CSLIBMSG_FUNC)(CS_CONTEXT *, CS_CLIENTMSG *)
Definition: cspublic.h:69
#define CS_SUCCEED
Definition: cspublic.h:40
#define CS_SYB_LANG_CHARSET
Definition: cspublic.h:513
#define CS_BLK_HAS_TEXT
Definition: cspublic.h:47
#define CS_ALLMSG_TYPE
Definition: cspublic.h:729
#define CS_QUIET
Definition: cspublic.h:44
#define CS_VARBINARY_TYPE
Definition: cspublic.h:569
#define CS_NULLTERM
Definition: cspublic.h:422
#define CS_CLEAR
Definition: cspublic.h:430
#define CS_STATUS
Definition: cspublic.h:432
#define CS_CONTINUE
Definition: cspublic.h:48
#define CS_NOMSG
Definition: cspublic.h:58
#define CS_ILLEGAL_TYPE
Definition: cspublic.h:549
#define CS_NVARCHAR_TYPE
Definition: cspublic.h:589
#define CS_END_RESULTS
Definition: cspublic.h:56
#define CS_FMT_NULLTERM
Definition: cspublic.h:400
#define CS_GET
Definition: cspublic.h:428
CS_RETCODE(* CS_CONV_FUNC)(CS_CONTEXT *context, CS_DATAFMT *srcfmt, CS_VOID *src, CS_DATAFMT *detsfmt, CS_VOID *dest, CS_INT *destlen)
Definition: cspublic.h:667
#define CS_FATAL
Definition: cspublic.h:49
#define CS_RET_HAFAILOVER
Definition: cspublic.h:50
Int4 CS_INT
Definition: cstypes.h:41
Int4 CS_BOOL
Definition: cstypes.h:52
#define CS_MAX_MSG
Definition: cstypes.h:69
void CS_VOID
Definition: cstypes.h:53
CS_INT CS_RETCODE
Definition: cstypes.h:63
char CS_CHAR
Definition: cstypes.h:48
static void _cs_locale_free_contents(CS_LOCALE *locale)
Definition: cs.c:233
CS_RETCODE cs_ctx_alloc(CS_INT version, CS_CONTEXT **ctx)
Definition: cs.c:342
CS_RETCODE cs_dt_crack_v2(CS_CONTEXT *ctx, CS_INT datetype, CS_VOID *dateval, CS_DATEREC *daterec)
Definition: cs.c:931
CS_LOCALE * _cs_locale_copy(CS_LOCALE *orig)
Definition: cs.c:300
static const char * _cs_get_layer(int layer)
Definition: cs.c:83
CS_RETCODE cs_dt_info(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_INT item, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: cs.c:1202
static CS_INT cs_diag_clearmsg(CS_CONTEXT *context, CS_INT type)
Definition: cs.c:1468
CS_RETCODE cs_strcmp(CS_CONTEXT *ctx, CS_LOCALE *locale, CS_INT type, CS_CHAR *str1, CS_INT len1, CS_CHAR *str2, CS_INT len2, CS_INT *result)
Definition: cs.c:1365
CS_RETCODE _cs_convert_ex(CS_CONTEXT *ctx, CS_DATAFMT *srcfmt, CS_VOID *srcdata, CS_DATAFMT *destfmt, CS_VOID *destdata, CS_INT *resultlen, TDS_SERVER_TYPE desttype, CS_VOID **handle)
Definition: cs.c:501
CS_RETCODE cs_locale(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: cs.c:1024
CS_RETCODE cs_dt_crack(CS_CONTEXT *ctx, CS_INT datetype, CS_VOID *dateval, CS_DATEREC *daterec)
Definition: cs.c:987
CS_RETCODE cs_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
Definition: cs.c:400
static const char * _cs_get_origin(int origin)
Definition: cs.c:98
CS_RETCODE cs_calc(CS_CONTEXT *ctx, CS_INT op, CS_INT datatype, CS_VOID *var1, CS_VOID *var2, CS_VOID *dest)
Definition: cs.c:1235
CS_RETCODE cs_set_convert(CS_CONTEXT *ctx, CS_INT action, CS_INT srctype, CS_INT desttype, CS_CONV_FUNC *func)
Definition: cs.c:1345
CS_RETCODE cs_will_convert(CS_CONTEXT *ctx, CS_INT srctype, CS_INT desttype, CS_BOOL *result)
Definition: cs.c:1387
static const char * _cs_get_user_api_layer_error(int error)
Definition: cs.c:122
CS_RETCODE cs_loc_alloc(CS_CONTEXT *ctx, CS_LOCALE **locptr)
Definition: cs.c:997
void _cs_locale_free(CS_LOCALE *locale)
Definition: cs.c:249
static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message)
Definition: cs.c:1397
int _cs_locale_copy_inplace(CS_LOCALE *new_locale, CS_LOCALE *orig)
Definition: cs.c:262
CS_RETCODE cs_ctx_drop(CS_CONTEXT *ctx)
Definition: cs.c:385
void _csclient_msg(CS_CONTEXT *ctx, const char *funcname, int layer, int origin, int severity, int number, const char *fmt,...)
Definition: cs.c:188
CS_RETCODE cs_diag(CS_CONTEXT *ctx, CS_INT operation, CS_INT type, CS_INT idx, CS_VOID *buffer)
Definition: cs.c:1265
CS_RETCODE cs_conv_mult(CS_CONTEXT *ctx, CS_LOCALE *srcloc, CS_LOCALE *destloc, CS_INT *conv_multiplier)
Definition: cs.c:1255
CS_RETCODE cs_strbuild(CS_CONTEXT *ctx, CS_CHAR *buffer, CS_INT buflen, CS_INT *resultlen, CS_CHAR *text, CS_INT textlen, CS_CHAR *formats, CS_INT formatlen,...)
Definition: cs.c:1218
static CS_INT cs_diag_getmsg(CS_CONTEXT *context, CS_INT idx, CS_CLIENTMSG *message)
Definition: cs.c:1439
CS_RETCODE cs_objects(CS_CONTEXT *ctx, CS_INT action, CS_OBJNAME *objname, CS_OBJDATA *objdata)
Definition: cs.c:1335
int _cs_convert_not_client(CS_CONTEXT *ctx, TDSCOLUMN *curcol, CONV_RESULT *convert_buffer, unsigned char **p_src)
Try to convert to a type we can handle.
Definition: cs.c:1508
CS_RETCODE cs_time(CS_CONTEXT *ctx, CS_LOCALE *locale, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen, CS_DATEREC *daterec)
Definition: cs.c:1377
CS_RETCODE cs_cmp(CS_CONTEXT *ctx, CS_INT datatype, CS_VOID *var1, CS_VOID *var2, CS_INT *result)
Definition: cs.c:1245
static CS_LOCALE * _cs_locale_alloc(void)
Allocate new CS_LOCALE and initialize it returns NULL on out of memory errors.
Definition: cs.c:225
CS_RETCODE cs_setnull(CS_CONTEXT *ctx, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT buflen)
Definition: cs.c:1355
CS_RETCODE cs_manage_convert(CS_CONTEXT *ctx, CS_INT action, CS_INT srctype, CS_CHAR *srcname, CS_INT srcnamelen, CS_INT desttype, CS_CHAR *destname, CS_INT destnamelen, CS_INT *conv_multiplier, CS_CONV_FUNC *func)
Definition: cs.c:1323
CS_RETCODE cs_ctx_global(CS_INT version, CS_CONTEXT **ctx)
Definition: cs.c:367
static char * _cs_get_msgstr(const char *funcname, int layer, int origin, int severity, int number)
Definition: cs.c:173
static CS_INT cs_diag_countmsg(CS_CONTEXT *context, CS_INT *count)
Definition: cs.c:1487
CS_RETCODE cs_loc_drop(CS_CONTEXT *ctx, CS_LOCALE *locale)
Definition: cs.c:1012
CS_RETCODE cs_convert(CS_CONTEXT *ctx, CS_DATAFMT *srcfmt, CS_VOID *srcdata, CS_DATAFMT *destfmt, CS_VOID *destdata, CS_INT *resultlen)
Definition: cs.c:494
const char * cs_prretcode(int retcode)
Definition: cs.c:48
#define strcat(s, k)
CS_CONTEXT * ctx
Definition: t0006.c:12
TDS_SERVER_TYPE _ct_get_server_type(TDSSOCKET *tds, int datatype)
Definition: ct.c:2128
#define _CS_ERRHAND_INLINE
Definition: ctlib.h:250
CS_INT _ct_diag_clearmsg(CS_CONTEXT *context, CS_INT type)
Definition: ct.c:4805
#define _CS_ERRHAND_CB
Definition: ctlib.h:251
#define TDS_CONVERT_SYNTAX
Definition: convert.h:78
#define TDS_CONVERT_OVERFLOW
Definition: convert.h:80
#define TDS_CONVERT_NOMEM
Definition: convert.h:79
#define TDS_CONVERT_NOAVAIL
Definition: convert.h:77
#define TDS_CONVERT_FAIL
Definition: convert.h:76
TDS_SERVER_TYPE
Definition: proto.h:161
@ SYBUINT8
Definition: proto.h:215
@ SYBLONGBINARY
Definition: proto.h:211
@ SYBUNIQUE
Definition: proto.h:199
@ SYBUINT2
Definition: proto.h:213
@ SYBUINT4
Definition: proto.h:214
@ SYB5BIGTIME
Definition: proto.h:231
@ SYB5BIGDATETIME
Definition: proto.h:230
@ SYBUINT1
Definition: proto.h:212
struct tdsnumeric TDS_NUMERIC
#define tds_new(type, n)
Definition: tds.h:1392
#define is_numeric_type(x)
Definition: tds.h:454
tds_sysdep_int32_type TDS_INT
Definition: tds.h:149
#define is_fixed_type(x)
Definition: tds.h:438
#define tdsdump_log
Definition: tds.h:1561
#define TDS_INVALID_TYPE
Definition: tds.h:160
#define tds_new0(type, n)
Definition: tds.h:1393
char TDS_CHAR
Definition: tds.h:144
int TDSRET
Definition: tds.h:201
#define TDS_SUCCEED(rc)
Definition: tds.h:207
#define TDS_DBG_FUNC
Definition: tds.h:898
#define asprintf
Definition: replacements.h:54
#define SYBMSDATE
Definition: sybdb.h:222
#define SYBINT4
Definition: sybdb.h:170
#define SYBNUMERIC
Definition: sybdb.h:202
#define SYBVARCHAR
Definition: sybdb.h:162
#define SYBTEXT
Definition: sybdb.h:182
#define SYBNVARCHAR
Definition: sybdb.h:212
#define SYBDATE
Definition: sybdb.h:214
#define SYBINT8
Definition: sybdb.h:172
#define SYBMSDATETIME2
Definition: sybdb.h:226
#define SYBNTEXT
Definition: sybdb.h:184
#define SYBIMAGE
Definition: sybdb.h:186
#define SYBMSDATETIMEOFFSET
Definition: sybdb.h:228
#define SYBINT1
Definition: sybdb.h:166
#define SYBDATETIME4
Definition: sybdb.h:192
#define SYBDECIMAL
Definition: sybdb.h:204
#define SYBCHAR
Definition: sybdb.h:160
#define SYBREAL
Definition: sybdb.h:194
#define SYBBITN
Definition: sybdb.h:180
#define SYBBINARY
Definition: sybdb.h:196
#define SYBTIME
Definition: sybdb.h:216
#define SYBMSTIME
Definition: sybdb.h:224
#define SYBDATETIME
Definition: sybdb.h:176
#define SYBVARBINARY
Definition: sybdb.h:200
#define SYBMONEY
Definition: sybdb.h:190
#define SYBMONEY4
Definition: sybdb.h:188
#define SYBFLT8
Definition: sybdb.h:174
#define SYBINT2
Definition: sybdb.h:168
#define SYBBIT
Definition: sybdb.h:178
#define STD_DATETIME_FMT
#define tds_get_size_by_type
#define tds_strndup
#define tds_numeric_bytes_per_prec
#define tds_alloc_context
#define tds_vstrbuild
#define tds_datecrack
#define tds_willconvert
#define tds_free_context
#define tds_convert
#define NULL
Definition: ncbistd.hpp:225
operation
Bit operations.
Definition: bmconst.h:191
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
where boath are integers</td > n< td ></td > n</tr > n< tr > n< td > tse</td > n< td > optional</td > n< td > String</td > n< td class=\"description\"> TSE option controls what blob is orig
int i
int len
static void text(MDB_val *v)
Definition: mdb_dump.c:62
static int version
Definition: mdb_load.c:29
#define strdup
Definition: ncbi_ansi_ext.h:70
static const GLdouble origin[]
static BOOL number
Definition: pcregrep.c:193
static char * locale
Definition: pcregrep.c:149
static pcre_uint8 * buffer
Definition: pcretest.c:1051
#define assert(x)
Definition: srv_diag.hpp:58
this structure is not directed connected to a TDS protocol but keeps any DATE/TIME information.
Definition: tds.h:167
CS_INT sqlstatelen
Definition: cstypes.h:195
CS_INT severity
Definition: cstypes.h:186
CS_MSGNUM msgnumber
Definition: cstypes.h:187
CS_INT status
Definition: cstypes.h:193
CS_INT osnumber
Definition: cstypes.h:190
CS_CHAR msgstring[1024]
Definition: cstypes.h:188
CS_INT msgstringlen
Definition: cstypes.h:189
CS_INT osstringlen
Definition: cstypes.h:192
CS_CHAR osstring[1024]
Definition: cstypes.h:191
TDSCONTEXT * tds_ctx
Definition: ctlib.h:107
CS_CSLIBMSG_FUNC _cslibmsg_cb
Definition: ctlib.h:100
struct cs_diag_msg * msgstore
Definition: ctlib.h:99
CS_INT cs_errhandletype
Definition: ctlib.h:85
int userdata_len
Definition: ctlib.h:105
CS_INT cs_diag_msglimit
Definition: ctlib.h:86
void * userdata
Definition: ctlib.h:104
CS_INT format
Definition: cstypes.h:126
CS_INT maxlength
Definition: cstypes.h:127
CS_INT precision
Definition: cstypes.h:129
CS_INT datatype
Definition: cstypes.h:125
CS_INT scale
Definition: cstypes.h:128
CS_INT datemonth
Definition: cstypes.h:169
CS_INT datesecprec
Definition: cstypes.h:179
CS_INT datetzone
Definition: cstypes.h:177
CS_INT datedmonth
Definition: cstypes.h:170
CS_INT datemsecond
Definition: cstypes.h:176
CS_INT dateyear
Definition: cstypes.h:168
CS_INT datesecfrac
Definition: cstypes.h:178
CS_INT dateminute
Definition: cstypes.h:174
CS_INT datehour
Definition: cstypes.h:173
CS_INT datedweek
Definition: cstypes.h:172
CS_INT datedyear
Definition: cstypes.h:171
CS_INT datesecond
Definition: cstypes.h:175
char * time
Definition: ctlib.h:257
char * collate
Definition: ctlib.h:258
char * language
Definition: ctlib.h:255
char * charset
Definition: ctlib.h:256
CS_SMALLINT len
Definition: cstypes.h:93
CS_CHAR str[256]
Definition: cstypes.h:94
Definition: inftrees.h:24
struct cs_diag_msg * next
Definition: ctlib.h:79
CS_CLIENTMSG * msg
Definition: ctlib.h:78
Metadata about columns in regular and compute rows.
Definition: tds.h:761
TDS_SERVER_TYPE column_type
This type can be different from wire type because conversion (e.g.
Definition: tds.h:768
TDS_INT column_cur_size
size written in variable (ie: char, text, binary).
Definition: tds.h:811
TDSLOCALE * locale
Definition: tds.h:1099
char * date_fmt
Definition: tds.h:650
Used by tds_datecrack.
Definition: tds.h:180
unsigned char scale
Definition: proto.h:28
unsigned char precision
Definition: proto.h:27
Definition: type.c:6
else result
Definition: token2.c:20
TDS_TINYINT ti
Definition: convert.h:36
TDS_CHAR * ib
Definition: convert.h:59
TDS_DATETIMEALL dta
Definition: convert.h:49
TDS_NUMERIC n
Definition: convert.h:54
TDS_CHAR * c
Definition: convert.h:58
static CS_CONTEXT * context
Definition: will_convert.c:21
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Thu Jul 18 16:06:16 2024 by modify_doxy.py rev. 669887