LTP GCOV extension - code coverage report
Current view: directory - ctlib - ctutil.c
Test: FreeTDS coverage
Date: 2008-09-03 Instrumented lines: 57
Code covered: 80.7 % Executed lines: 46

       1                 : /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
       2                 :  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
       3                 :  *
       4                 :  * This library is free software; you can redistribute it and/or
       5                 :  * modify it under the terms of the GNU Library General Public
       6                 :  * License as published by the Free Software Foundation; either
       7                 :  * version 2 of the License, or (at your option) any later version.
       8                 :  *
       9                 :  * This library is distributed in the hope that it will be useful,
      10                 :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11                 :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      12                 :  * Library General Public License for more details.
      13                 :  *
      14                 :  * You should have received a copy of the GNU Library General Public
      15                 :  * License along with this library; if not, write to the
      16                 :  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
      17                 :  * Boston, MA 02111-1307, USA.
      18                 :  */
      19                 : 
      20                 : #if HAVE_CONFIG_H
      21                 : #include <config.h>
      22                 : #endif /* HAVE_CONFIG_H */
      23                 : 
      24                 : #if HAVE_STRING_H
      25                 : #include <string.h>
      26                 : #endif /* HAVE_STRING_H */
      27                 : 
      28                 : #include "cspublic.h"
      29                 : #include "ctlib.h"
      30                 : #include "tds.h"
      31                 : #include "replacements.h"
      32                 : /* #include "fortify.h" */
      33                 : 
      34                 : 
      35                 : TDS_RCSID(var, "$Id: ctutil.c,v 1.29 2008/08/17 07:44:45 freddy77 Exp $");
      36                 : 
      37                 : /*
      38                 :  * test include consistency 
      39                 :  * I don't think all compiler are able to compile this code... if not comment it
      40                 :  */
      41                 : #if ENABLE_EXTRA_CHECKS
      42                 : 
      43                 : #if defined(__GNUC__) && __GNUC__ >= 2
      44                 : #define COMPILE_CHECK(name,check) \
      45                 :     extern int name[(check)?1:-1] __attribute__ ((unused))
      46                 : #else
      47                 : #define COMPILE_CHECK(name,check) \
      48                 :     extern int name[(check)?1:-1]
      49                 : #endif
      50                 : 
      51                 : #define TEST_EQUAL(t,a,b) COMPILE_CHECK(t,a==b)
      52                 : 
      53                 : TEST_EQUAL(t01,CS_FAIL,TDS_FAIL);
      54                 : TEST_EQUAL(t02,CS_SUCCEED,TDS_SUCCEED);
      55                 : TEST_EQUAL(t03,CS_NULLTERM,TDS_NULLTERM);
      56                 : TEST_EQUAL(t04,CS_CMD_SUCCEED,TDS_CMD_SUCCEED);
      57                 : TEST_EQUAL(t05,CS_CMD_FAIL,TDS_CMD_FAIL);
      58                 : TEST_EQUAL(t06,CS_CMD_DONE,TDS_CMD_DONE);
      59                 : TEST_EQUAL(t07,CS_NO_COUNT,TDS_NO_COUNT);
      60                 : TEST_EQUAL(t08,CS_COMPUTE_RESULT,TDS_COMPUTE_RESULT);
      61                 : TEST_EQUAL(t09,CS_PARAM_RESULT,TDS_PARAM_RESULT);
      62                 : TEST_EQUAL(t10,CS_ROW_RESULT,TDS_ROW_RESULT);
      63                 : TEST_EQUAL(t11,CS_STATUS_RESULT,TDS_STATUS_RESULT);
      64                 : TEST_EQUAL(t12,CS_COMPUTEFMT_RESULT,TDS_COMPUTEFMT_RESULT);
      65                 : TEST_EQUAL(t13,CS_ROWFMT_RESULT,TDS_ROWFMT_RESULT);
      66                 : TEST_EQUAL(t14,CS_MSG_RESULT,TDS_MSG_RESULT);
      67                 : TEST_EQUAL(t15,CS_DESCRIBE_RESULT,TDS_DESCRIBE_RESULT);
      68                 : 
      69                 : #define TEST_ATTRIBUTE(t,sa,fa,sb,fb) \
      70                 :         COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && (TDS_INTPTR)(&((sa*)0)->fa) == (TDS_INTPTR)(&((sb*)0)->fb))
      71                 : 
      72                 : TEST_ATTRIBUTE(t21,TDS_MONEY4,mny4,CS_MONEY4,mny4);
      73                 : TEST_ATTRIBUTE(t22,TDS_OLD_MONEY,mnyhigh,CS_MONEY,mnyhigh);
      74                 : TEST_ATTRIBUTE(t23,TDS_OLD_MONEY,mnylow,CS_MONEY,mnylow);
      75                 : TEST_ATTRIBUTE(t24,TDS_DATETIME,dtdays,CS_DATETIME,dtdays);
      76                 : TEST_ATTRIBUTE(t25,TDS_DATETIME,dttime,CS_DATETIME,dttime);
      77                 : TEST_ATTRIBUTE(t26,TDS_DATETIME4,days,CS_DATETIME4,days);
      78                 : TEST_ATTRIBUTE(t27,TDS_DATETIME4,minutes,CS_DATETIME4,minutes);
      79                 : TEST_ATTRIBUTE(t28,TDS_NUMERIC,precision,CS_NUMERIC,precision);
      80                 : TEST_ATTRIBUTE(t29,TDS_NUMERIC,scale,CS_NUMERIC,scale);
      81                 : TEST_ATTRIBUTE(t30,TDS_NUMERIC,array,CS_NUMERIC,array);
      82                 : TEST_ATTRIBUTE(t30,TDS_NUMERIC,precision,CS_DECIMAL,precision);
      83                 : TEST_ATTRIBUTE(t31,TDS_NUMERIC,scale,CS_DECIMAL,scale);
      84                 : TEST_ATTRIBUTE(t32,TDS_NUMERIC,array,CS_DECIMAL,array);
      85                 : TEST_ATTRIBUTE(t33,TDS_VARBINARY,len,CS_VARBINARY,len);
      86                 : TEST_ATTRIBUTE(t34,TDS_VARBINARY,array,CS_VARBINARY,array);
      87                 : #endif
      88                 : 
      89                 : /* 
      90                 :  * error handler 
      91                 :  * This callback function should be invoked only from libtds through tds_ctx->err_handler.  
      92                 :  */
      93                 : int
      94                 : _ct_handle_client_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAGE * msg)
      95               3 : {
      96                 :         CS_CLIENTMSG errmsg;
      97               3 :         CS_CONNECTION *con = NULL;
      98               3 :         CS_CONTEXT *ctx = NULL;
      99               3 :         int ret = (int) CS_SUCCEED;
     100                 : 
     101               3 :         if (tds && tds->parent) {
     102               3 :                 con = (CS_CONNECTION *) tds->parent;
     103                 :         }
     104                 : 
     105               3 :         memset(&errmsg, '\0', sizeof(errmsg));
     106               3 :         errmsg.msgnumber = msg->msgno;
     107               3 :         strcpy(errmsg.msgstring, msg->message);
     108               3 :         errmsg.msgstringlen = strlen(msg->message);
     109               3 :         errmsg.osstring[0] = '\0';
     110               3 :         errmsg.osstringlen = 0;
     111                 :         /* if there is no connection, attempt to call the context handler */
     112               3 :         if (!con) {
     113               0 :                 ctx = (CS_CONTEXT *) ctx_tds->parent;
     114               0 :                 if (ctx->_clientmsg_cb)
     115               0 :                         ret = ctx->_clientmsg_cb(ctx, con, &errmsg);
     116               3 :         } else if (con->_clientmsg_cb)
     117               0 :                 ret = con->_clientmsg_cb(con->ctx, con, &errmsg);
     118               3 :         else if (con->ctx->_clientmsg_cb)
     119               0 :                 ret = con->ctx->_clientmsg_cb(con->ctx, con, &errmsg);
     120                 :                 
     121                 :         /*
     122                 :          * The return code from the error handler is either CS_SUCCEED or CS_FAIL.
     123                 :          * This function was called by libtds with some kind of communications failure, and there are
     124                 :          * no cases in which "succeed" could mean anything: In most cases, the function is going to fail
     125                 :          * no matter what.  
     126                 :          *
     127                 :          * Timeouts are a different matter; it's up to the client to decide whether to continue
     128                 :          * waiting or to abort the operation and close the socket.  ct-lib applications do their 
     129                 :          * own cancel processing -- they can call ct_cancel from within the error handler -- so 
     130                 :          * they don't need to return TDS_INT_TIMEOUT.  They can, however, return TDS_INT_CONTINUE
     131                 :          * or TDS_INT_CANCEL.  We map the client's return code to those. 
     132                 :          *
     133                 :          * Only for timeout errors does TDS_INT_CANCEL cause libtds to break the connection. 
     134                 :          */
     135               3 :         if (msg->msgno == TDSETIME) {
     136               0 :                 switch (ret) {
     137               0 :                 case CS_SUCCEED:        return TDS_INT_CONTINUE;
     138               0 :                 case CS_FAIL:           return TDS_INT_CANCEL;
     139                 :                 }
     140                 :         }
     141               3 :         return TDS_INT_CANCEL;
     142                 : }
     143                 : 
     144                 : /* message handler */
     145                 : int
     146                 : _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAGE * msg)
     147            1156 : {
     148                 :         CS_SERVERMSG errmsg;
     149            1156 :         CS_CONNECTION *con = NULL;
     150            1156 :         CS_CONTEXT *ctx = NULL;
     151            1156 :         int ret = (int) CS_SUCCEED;
     152                 : 
     153            1156 :         if (tds && tds->parent) {
     154            1156 :                 con = (CS_CONNECTION *) tds->parent;
     155                 :         }
     156                 : 
     157            1156 :         memset(&errmsg, '\0', sizeof(errmsg));
     158            1156 :         errmsg.msgnumber = msg->msgno;
     159            1156 :         tds_strlcpy(errmsg.text, msg->message, sizeof(errmsg.text));
     160            1156 :         errmsg.textlen = strlen(errmsg.text);
     161            1156 :         errmsg.sqlstate[0] = 0;
     162            1156 :         if (msg->sql_state)
     163              23 :                 tds_strlcpy((char *) errmsg.sqlstate, msg->sql_state, sizeof(errmsg.sqlstate));
     164            1156 :         errmsg.sqlstatelen = strlen((char *) errmsg.sqlstate);
     165            1156 :         errmsg.state = msg->state;
     166            1156 :         errmsg.severity = msg->severity;
     167            1156 :         errmsg.line = msg->line_number;
     168            1156 :         if (msg->server) {
     169            1156 :                 errmsg.svrnlen = strlen(msg->server);
     170            1156 :                 tds_strlcpy(errmsg.svrname, msg->server, CS_MAX_NAME);
     171                 :         }
     172            1156 :         if (msg->proc_name) {
     173            1156 :                 errmsg.proclen = strlen(msg->proc_name);
     174            1156 :                 tds_strlcpy(errmsg.proc, msg->proc_name, CS_MAX_NAME);
     175                 :         }
     176                 :         /* if there is no connection, attempt to call the context handler */
     177            1156 :         if (!con) {
     178               0 :                 ctx = (CS_CONTEXT *) ctx_tds->parent;
     179               0 :                 if (ctx->_servermsg_cb)
     180               0 :                         ret = ctx->_servermsg_cb(ctx, con, &errmsg);
     181            1156 :         } else if (con->_servermsg_cb) {
     182               3 :                 ret = con->_servermsg_cb(con->ctx, con, &errmsg);
     183            1153 :         } else if (con->ctx->_servermsg_cb) {
     184            1150 :                 ret = con->ctx->_servermsg_cb(con->ctx, con, &errmsg);
     185                 :         }
     186            1156 :         return ret;
     187                 : }

Generated by: LTP GCOV extension version 1.6