NCBI C++ ToolKit
ctutil.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 Brian Bruns
3  * Copyright (C) 2011 Frediano Ziglio
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include <config.h>
22 
23 #if HAVE_STRING_H
24 #include <string.h>
25 #endif /* HAVE_STRING_H */
26 
27 #include "cspublic.h"
28 #include "ctlib.h"
29 #include "syberror.h"
30 #include <freetds/tds.h>
31 #include "replacements.h"
32 /* #include "fortify.h" */
33 
34 
35 /*
36  * test include consistency
37  * I don't think all compiler are able to compile this code... if not comment it
38  */
39 #if ENABLE_EXTRA_CHECKS
40 
41 #define TEST_EQUAL(t,a,b) TDS_COMPILE_CHECK(t,a==b)
42 
43 TEST_EQUAL(t03,CS_NULLTERM,TDS_NULLTERM);
44 TEST_EQUAL(t04,CS_CMD_SUCCEED,TDS_CMD_SUCCEED);
45 TEST_EQUAL(t05,CS_CMD_FAIL,TDS_CMD_FAIL);
46 TEST_EQUAL(t06,CS_CMD_DONE,TDS_CMD_DONE);
47 TEST_EQUAL(t07,CS_NO_COUNT,TDS_NO_COUNT);
49 TEST_EQUAL(t09,CS_PARAM_RESULT,TDS_PARAM_RESULT);
50 TEST_EQUAL(t10,CS_ROW_RESULT,TDS_ROW_RESULT);
51 TEST_EQUAL(t11,CS_STATUS_RESULT,TDS_STATUS_RESULT);
53 TEST_EQUAL(t13,CS_ROWFMT_RESULT,TDS_ROWFMT_RESULT);
54 TEST_EQUAL(t14,CS_MSG_RESULT,TDS_MSG_RESULT);
56 
57 #define TEST_ATTRIBUTE(t,sa,fa,sb,fb) \
58  TDS_COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && TDS_OFFSET(sa,fa) == TDS_OFFSET(sb,fb))
59 
60 TEST_ATTRIBUTE(t21,TDS_MONEY4,mny4,CS_MONEY4,mny4);
61 TEST_ATTRIBUTE(t22,TDS_OLD_MONEY,mnyhigh,CS_MONEY,mnyhigh);
62 TEST_ATTRIBUTE(t23,TDS_OLD_MONEY,mnylow,CS_MONEY,mnylow);
63 TEST_ATTRIBUTE(t24,TDS_DATETIME,dtdays,CS_DATETIME,dtdays);
64 TEST_ATTRIBUTE(t25,TDS_DATETIME,dttime,CS_DATETIME,dttime);
65 TEST_ATTRIBUTE(t26,TDS_DATETIME4,days,CS_DATETIME4,days);
66 TEST_ATTRIBUTE(t27,TDS_DATETIME4,minutes,CS_DATETIME4,minutes);
67 TEST_ATTRIBUTE(t28,TDS_NUMERIC,precision,CS_NUMERIC,precision);
68 TEST_ATTRIBUTE(t29,TDS_NUMERIC,scale,CS_NUMERIC,scale);
69 TEST_ATTRIBUTE(t30,TDS_NUMERIC,array,CS_NUMERIC,array);
70 TEST_ATTRIBUTE(t30,TDS_NUMERIC,precision,CS_DECIMAL,precision);
71 TEST_ATTRIBUTE(t31,TDS_NUMERIC,scale,CS_DECIMAL,scale);
72 TEST_ATTRIBUTE(t32,TDS_NUMERIC,array,CS_DECIMAL,array);
73 #endif
74 
75 static
76 int _ct_translate_severity(int tds_severity)
77 {
78  switch (tds_severity) {
79  case 0:
80  case EXINFO: return CS_SV_INFORM; /* unused */
81  case EXUSER: return CS_SV_CONFIG_FAIL;
82  case EXNONFATAL: return CS_SV_INTERNAL_FAIL; /* unused */
83  case EXCONVERSION: return CS_SV_API_FAIL;
84  case EXSERVER: return CS_SV_INTERNAL_FAIL; /* unused */
85  case EXTIME: return CS_SV_RETRY_FAIL;
86  case EXPROGRAM: return CS_SV_API_FAIL;
87  case EXRESOURCE: return CS_SV_RESOURCE_FAIL; /* unused */
88  case EXCOMM: return CS_SV_COMM_FAIL;
89  case EXFATAL: return CS_SV_FATAL;
90  case EXCONSISTENCY:
91  default: return CS_SV_INTERNAL_FAIL;
92  }
93 }
94 
95 /*
96  * error handler
97  * This callback function should be invoked only from libtds through tds_ctx->err_handler.
98  */
99 int
101 {
102  CS_CLIENTMSG errmsg;
103  CS_CONNECTION *con = NULL;
104  CS_CONTEXT *ctx = NULL;
105  int ret = (int) CS_SUCCEED;
106 
107  tdsdump_log(TDS_DBG_FUNC, "_ct_handle_client_message(%p, %p, %p)\n", ctx_tds, tds, msg);
108 
109  if (tds && tds_get_parent(tds)) {
110  con = (CS_CONNECTION *) tds_get_parent(tds);
111  }
112 
113  memset(&errmsg, '\0', sizeof(errmsg));
114  errmsg.msgnumber = msg->msgno;
115  errmsg.severity = _ct_translate_severity(msg->severity);
116  strlcpy(errmsg.msgstring, msg->message, sizeof(errmsg.msgstring));
117  errmsg.msgstringlen = (CS_INT)strlen(errmsg.msgstring);
118  if (msg->osstr) {
119  errmsg.osstringlen = (CS_INT)strlen(msg->osstr);
120  strlcpy(errmsg.osstring, msg->osstr, CS_MAX_MSG);
121  }
122 
123  /* if there is no connection, attempt to call the context handler */
124  if (!con) {
125  ctx = (CS_CONTEXT *) ctx_tds->parent;
126  if (ctx->_clientmsg_cb)
127  ret = ctx->_clientmsg_cb(ctx, con, &errmsg);
128  } else if (con->_clientmsg_cb)
129  ret = con->_clientmsg_cb(con->ctx, con, &errmsg);
130  else if (con->ctx->_clientmsg_cb)
131  ret = con->ctx->_clientmsg_cb(con->ctx, con, &errmsg);
132 
133  /*
134  * The return code from the error handler is either CS_SUCCEED or CS_FAIL.
135  * This function was called by libtds with some kind of communications failure, and there are
136  * no cases in which "succeed" could mean anything: In most cases, the function is going to fail
137  * no matter what.
138  *
139  * Timeouts are a different matter; it's up to the client to decide whether to continue
140  * waiting or to abort the operation and close the socket. ct-lib applications do their
141  * own cancel processing -- they can call ct_cancel from within the error handler -- so
142  * they don't need to return TDS_INT_TIMEOUT. They can, however, return TDS_INT_CONTINUE
143  * or TDS_INT_CANCEL. We map the client's return code to those.
144  *
145  * Only for timeout errors does TDS_INT_CANCEL cause libtds to break the connection.
146  */
147  if (msg->msgno == TDSETIME) {
148  switch (ret) {
149  case CS_SUCCEED: return TDS_INT_CONTINUE;
150  case CS_FAIL: return TDS_INT_CANCEL;
151  }
152  }
153  return TDS_INT_CANCEL;
154 }
155 
156 /* message handler */
157 TDSRET
159 {
160  CS_SERVERMSG errmsg;
161  CS_CONNECTION *con = NULL;
162  CS_CONTEXT *ctx = NULL;
163  CS_RETCODE ret = CS_SUCCEED;
164 
165  tdsdump_log(TDS_DBG_FUNC, "_ct_handle_server_message(%p, %p, %p)\n", ctx_tds, tds, msg);
166 
167  if (tds && tds_get_parent(tds))
168  con = (CS_CONNECTION *) tds_get_parent(tds);
169 
170  memset(&errmsg, '\0', sizeof(errmsg));
171  errmsg.msgnumber = msg->msgno;
172  strlcpy(errmsg.text, msg->message, sizeof(errmsg.text));
173  errmsg.textlen = (CS_INT) strlen(errmsg.text);
174  errmsg.sqlstate[0] = 0;
175  if (msg->sql_state)
176  strlcpy((char *) errmsg.sqlstate, msg->sql_state, sizeof(errmsg.sqlstate));
177  errmsg.sqlstatelen = (CS_INT) strlen((char *) errmsg.sqlstate);
178  errmsg.state = msg->state;
179  errmsg.severity = msg->severity;
180  errmsg.line = msg->line_number;
181  if (msg->server) {
182  errmsg.svrnlen = (CS_INT) strlen(msg->server);
183  strlcpy(errmsg.svrname, msg->server, CS_MAX_NAME);
184  }
185  if (msg->proc_name) {
186  errmsg.proclen = (CS_INT) strlen(msg->proc_name);
187  strlcpy(errmsg.proc, msg->proc_name, CS_MAX_NAME);
188  }
189  /* if there is no connection, attempt to call the context handler */
190  if (!con) {
191  ctx = (CS_CONTEXT *) ctx_tds->parent;
192  if (ctx->_servermsg_cb)
193  ret = ctx->_servermsg_cb(ctx, con, &errmsg);
194  } else if (con->_servermsg_cb) {
195  ret = con->_servermsg_cb(con->ctx, con, &errmsg);
196  } else if (con->ctx->_servermsg_cb) {
197  ret = con->ctx->_servermsg_cb(con->ctx, con, &errmsg);
198  }
199  return ret == CS_SUCCEED ? TDS_SUCCESS : TDS_FAIL;
200 }
#define CS_CMD_DONE
Definition: cspublic.h:436
#define CS_CMD_SUCCEED
Definition: cspublic.h:437
#define CS_FAIL
Definition: cspublic.h:41
#define CS_SV_RESOURCE_FAIL
Definition: cspublic.h:531
#define CS_PARAM_RESULT
Definition: cspublic.h:540
#define CS_SV_API_FAIL
Definition: cspublic.h:529
#define CS_COMPUTEFMT_RESULT
Definition: cspublic.h:543
#define CS_MSG_RESULT
Definition: cspublic.h:545
#define CS_SV_COMM_FAIL
Definition: cspublic.h:533
#define CS_SV_INTERNAL_FAIL
Definition: cspublic.h:534
#define CS_SV_FATAL
Definition: cspublic.h:535
#define CS_SV_CONFIG_FAIL
Definition: cspublic.h:532
#define CS_STATUS_RESULT
Definition: cspublic.h:542
#define CS_ROWFMT_RESULT
Definition: cspublic.h:544
#define CS_DESCRIBE_RESULT
Definition: cspublic.h:546
#define CS_ROW_RESULT
Definition: cspublic.h:541
#define CS_COMPUTE_RESULT
Definition: cspublic.h:538
#define CS_SUCCEED
Definition: cspublic.h:40
#define CS_CMD_FAIL
Definition: cspublic.h:438
#define CS_NULLTERM
Definition: cspublic.h:422
#define CS_SV_INFORM
Definition: cspublic.h:528
#define CS_SV_RETRY_FAIL
Definition: cspublic.h:530
#define CS_NO_COUNT
Definition: cspublic.h:490
Int4 CS_INT
Definition: cstypes.h:41
#define CS_MAX_NAME
Definition: cstypes.h:65
#define CS_MAX_MSG
Definition: cstypes.h:69
CS_INT CS_RETCODE
Definition: cstypes.h:63
int _ct_handle_client_message(const TDSCONTEXT *ctx_tds, TDSSOCKET *tds, TDSMESSAGE *msg)
Definition: ctutil.c:100
static int _ct_translate_severity(int tds_severity)
Definition: ctutil.c:76
TDSRET _ct_handle_server_message(const TDSCONTEXT *ctx_tds, TDSSOCKET *tds, TDSMESSAGE *msg)
Definition: ctutil.c:158
CS_CONTEXT * ctx
Definition: t0006.c:12
#define TDS_FAIL
Definition: tds.h:204
#define TDS_NO_COUNT
Definition: tds.h:214
#define TDS_ROWFMT_RESULT
Definition: tds.h:224
#define tds_get_parent(tds)
Definition: tds.h:1296
#define TDS_MSG_RESULT
Definition: tds.h:219
#define tdsdump_log
Definition: tds.h:1561
#define TDS_COMPUTEFMT_RESULT
Definition: tds.h:225
#define TDS_INT_CONTINUE
Definition: tds.h:209
#define TDS_CMD_FAIL
Definition: tds.h:223
#define TDS_INT_CANCEL
Definition: tds.h:210
#define TDS_DESCRIBE_RESULT
Definition: tds.h:226
#define TDS_COMPUTE_RESULT
Definition: tds.h:220
#define TDS_CMD_SUCCEED
Definition: tds.h:222
#define TDS_CMD_DONE
Definition: tds.h:221
#define TDS_PARAM_RESULT
Definition: tds.h:217
@ TDSETIME
Definition: tds.h:305
#define TDS_ROW_RESULT
Definition: tds.h:216
int TDSRET
Definition: tds.h:201
#define TDS_SUCCESS
Definition: tds.h:203
#define TDS_STATUS_RESULT
Definition: tds.h:218
#define TDS_DBG_FUNC
Definition: tds.h:898
#define TDS_NULLTERM
Definition: tds.h:344
static char precision
Definition: genparams.c:28
#define strlcpy(d, s, l)
Definition: replacements.h:80
#define EXCONSISTENCY
Definition: syberror.h:45
#define EXNONFATAL
Definition: syberror.h:37
#define EXINFO
Definition: syberror.h:35
#define EXCONVERSION
Definition: syberror.h:38
#define EXFATAL
Definition: syberror.h:44
#define EXCOMM
Definition: syberror.h:43
#define EXTIME
Definition: syberror.h:40
#define EXPROGRAM
Definition: syberror.h:41
#define EXSERVER
Definition: syberror.h:39
#define EXUSER
Definition: syberror.h:36
#define EXRESOURCE
Definition: syberror.h:42
static TDSSOCKET * tds
Definition: collations.c:37
#define NULL
Definition: ncbistd.hpp:225
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
if(yy_accept[yy_current_state])
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
CS_INT severity
Definition: cstypes.h:186
CS_MSGNUM msgnumber
Definition: cstypes.h:187
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
CS_CONTEXT * ctx
Definition: ctlib.h:125
CS_SERVERMSG_FUNC _servermsg_cb
Definition: ctlib.h:129
CS_CLIENTMSG_FUNC _clientmsg_cb
Definition: ctlib.h:128
CS_SERVERMSG_FUNC _servermsg_cb
Definition: ctlib.h:102
CS_CLIENTMSG_FUNC _clientmsg_cb
Definition: ctlib.h:101
CS_MSGNUM msgnumber
Definition: cstypes.h:200
CS_INT line
Definition: cstypes.h:209
CS_CHAR text[1024]
Definition: cstypes.h:203
CS_CHAR proc[132]
Definition: cstypes.h:207
CS_BYTE sqlstate[8]
Definition: cstypes.h:211
CS_INT sqlstatelen
Definition: cstypes.h:212
CS_INT svrnlen
Definition: cstypes.h:206
CS_INT severity
Definition: cstypes.h:202
CS_INT proclen
Definition: cstypes.h:208
CS_CHAR svrname[132]
Definition: cstypes.h:205
CS_INT state
Definition: cstypes.h:201
CS_INT textlen
Definition: cstypes.h:204
void * parent
Definition: tds.h:1100
Information for a server connection.
Definition: tds.h:1211
Modified on Fri Sep 20 14:58:18 2024 by modify_doxy.py rev. 669887