LCOV - code coverage report
Current view: top level - src/ctlib/unittests - common.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 123 210 58.6 %
Date: 2024-03-23 09:12:27 Functions: 11 11 100.0 %

          Line data    Source code
       1             : #include <config.h>
       2             : 
       3             : #include <stdio.h>
       4             : 
       5             : #if HAVE_STDLIB_H
       6             : #include <stdlib.h>
       7             : #endif /* HAVE_STDLIB_H */
       8             : 
       9             : #if HAVE_STRING_H
      10             : #include <string.h>
      11             : #endif /* HAVE_STRING_H */
      12             : 
      13             : #if HAVE_UNISTD_H
      14             : #include <unistd.h>
      15             : #endif
      16             : 
      17             : #ifndef DBNTWIN32
      18             : #include <freetds/replacements.h>
      19             : #endif
      20             : 
      21             : #include <ctpublic.h>
      22             : #include "common.h"
      23             : #ifdef TDS_STATIC_CAST
      24             : #include "ctlib.h"
      25             : #endif
      26             : 
      27             : char USER[512];
      28             : char SERVER[512];
      29             : char PASSWORD[512];
      30             : char DATABASE[512];
      31             : 
      32             : COMMON_PWD common_pwd = {0};
      33             : 
      34             : static char *DIRNAME = NULL;
      35             : static const char *BASENAME = NULL;
      36             : 
      37             : static const char *PWD = "../../../PWD";
      38             : 
      39             : 
      40             : int cslibmsg_cb_invoked = 0;
      41             : int clientmsg_cb_invoked = 0;
      42             : int servermsg_cb_invoked = 0;
      43             : 
      44             : static CS_RETCODE continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose);
      45             : 
      46             : #if defined(__MINGW32__) || defined(_MSC_VER)
      47             : static char *
      48             : tds_dirname(char* path)
      49             : {
      50             :         char *p, *p2;
      51             : 
      52             :         for (p = path + strlen(path); --p > path && (*p == '/' || *p == '\\');)
      53             :                 *p = '\0';
      54             : 
      55             :         p = strrchr(path, '/');
      56             :         if (!p)
      57             :                 p = path;
      58             :         p2 = strrchr(p, '\\');
      59             :         if (p2)
      60             :                 p = p2;
      61             :         *p = 0;
      62             :         return path;
      63             : }
      64             : #define dirname tds_dirname
      65             : 
      66             : #endif
      67             : 
      68             : CS_RETCODE
      69        1048 : read_login_info(void)
      70             : {
      71        1048 :         FILE *in = NULL;
      72             :         char line[512];
      73             :         char *s1, *s2;
      74             : 
      75        1048 :         if (common_pwd.initialized) {
      76           0 :                 strcpy(USER, common_pwd.USER);
      77           0 :                 strcpy(PASSWORD, common_pwd.PASSWORD);
      78           0 :                 strcpy(SERVER, common_pwd.SERVER);
      79           0 :                 strcpy(DATABASE, common_pwd.DATABASE);
      80           0 :                 return CS_SUCCEED;
      81             :         }
      82             : 
      83        1048 :         s1 = getenv("TDSPWDFILE");
      84        1048 :         if (s1 && s1[0])
      85           0 :                 in = fopen(s1, "r");
      86           0 :         if (!in)
      87        1048 :                 in = fopen(PWD, "r");
      88        1048 :         if (!in) {
      89           0 :                 fprintf(stderr, "Can not open PWD file \"%s\"\n\n", PWD);
      90           0 :                 return CS_FAIL;
      91             :         }
      92             : 
      93       19912 :         while (fgets(line, sizeof(line), in)) {
      94       18864 :                 s1 = strtok(line, "=");
      95       18864 :                 s2 = strtok(NULL, "\n");
      96       18864 :                 if (!s1 || !s2) {
      97       11266 :                         continue;
      98             :                 }
      99        7598 :                 if (!strcmp(s1, "UID")) {
     100        1048 :                         strcpy(USER, s2);
     101        6550 :                 } else if (!strcmp(s1, "SRV")) {
     102        1048 :                         strcpy(SERVER, s2);
     103        5502 :                 } else if (!strcmp(s1, "PWD")) {
     104        1048 :                         strcpy(PASSWORD, s2);
     105        4454 :                 } else if (!strcmp(s1, "DB")) {
     106        1048 :                         strcpy(DATABASE, s2);
     107             :                 }
     108             :         }
     109        1048 :         fclose(in);
     110        1048 :         return CS_SUCCEED;
     111             : }
     112             : 
     113             : static CS_RETCODE
     114          16 : establish_login(int argc, char **argv)
     115             : {
     116             :         extern char *optarg;
     117             :         extern int optind;
     118          16 :         COMMON_PWD options = {0};
     119             : #if !defined(__MINGW32__) && !defined(_MSC_VER)
     120             :         int ch;
     121             : #endif
     122             : 
     123          16 :         BASENAME = basename((char *)argv[0]);
     124          16 :         DIRNAME = dirname((char *)argv[0]);
     125             : 
     126             : #if !defined(__MINGW32__) && !defined(_MSC_VER)
     127             :         /* process command line options (handy for manual testing) */
     128          32 :         while ((ch = getopt(argc, argv, "U:P:S:D:f:m:v")) != -1) {
     129           0 :                 switch (ch) {
     130           0 :                 case 'U':
     131           0 :                         strcpy(options.USER, optarg);
     132           0 :                         break;
     133           0 :                 case 'P':
     134           0 :                         strcpy(options.PASSWORD, optarg);
     135           0 :                         break;
     136           0 :                 case 'S':
     137           0 :                         strcpy(options.SERVER, optarg);
     138           0 :                         break;
     139           0 :                 case 'D':
     140           0 :                         strcpy(options.DATABASE, optarg);
     141           0 :                         break;
     142           0 :                 case 'f': /* override default PWD file */
     143           0 :                         PWD = strdup(optarg);
     144           0 :                         break;
     145           0 :                 case 'm':
     146           0 :                         common_pwd.maxlength = strtol(optarg, NULL, 10);
     147           0 :                 case 'v':
     148           0 :                         common_pwd.fverbose = 1;
     149           0 :                         break;
     150           0 :                 case '?':
     151             :                 default:
     152           0 :                         fprintf(stderr, "usage:  %s [-v] [-f PWD]\n"
     153             :                                         "        [-U username] [-P password]\n"
     154             :                                         "        [-S servername] [-D database]\n"
     155             :                                         , BASENAME);
     156           0 :                         exit(1);
     157             :                 }
     158             :         }
     159             : #endif
     160          16 :         read_login_info();
     161             : 
     162             :         /* override PWD file with command-line options */
     163             : 
     164          16 :         if (*options.USER)
     165           0 :                 strcpy(USER, options.USER);
     166          16 :         if (*options.PASSWORD)
     167           0 :                 strcpy(PASSWORD, options.PASSWORD);
     168          16 :         if (*options.SERVER)
     169           0 :                 strcpy(SERVER, options.SERVER);
     170          16 :         if (*options.DATABASE)
     171           0 :                 strcpy(DATABASE, options.DATABASE);
     172             : 
     173          16 :         return (*USER && *SERVER && *DATABASE)? CS_SUCCEED : CS_FAIL;
     174             : }
     175             : 
     176             : CS_RETCODE
     177          16 : try_ctlogin_with_options(int argc, char **argv, CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
     178             : {
     179             :         CS_RETCODE ret;
     180             : 
     181          16 :         if ((ret = establish_login(argc, argv)) != CS_SUCCEED) {
     182           0 :                 if (verbose) {
     183           0 :                         fprintf(stderr, "read_login_info() failed!\n");
     184             :                 }
     185             :                 return ret;
     186             :         }
     187          16 :         return continue_logging_in(ctx, conn, cmd, verbose);
     188             : }
     189             : 
     190             : /* old way: because I'm too lazy to change every unit test */
     191             : CS_RETCODE
     192        1024 : try_ctlogin(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
     193             : {
     194             :         CS_RETCODE ret;
     195             : 
     196        1024 :         if ((ret = read_login_info()) != CS_SUCCEED) {
     197           0 :                 if (verbose) {
     198           0 :                         fprintf(stderr, "read_login_info() failed!\n");
     199             :                 }
     200             :                 return ret;
     201             :         }
     202        1024 :         return continue_logging_in(ctx, conn, cmd, verbose);
     203             : }
     204             : 
     205             : CS_RETCODE
     206        1040 : continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
     207             : {
     208             :         CS_RETCODE ret;
     209             :         char query[512+10];
     210             : #ifdef TDS_STATIC_CAST
     211             :         TDSCONTEXT *tds_ctx;
     212             : #endif
     213             : 
     214        1040 :         ret = cs_ctx_alloc(CS_VERSION_100, ctx);
     215        1040 :         if (ret != CS_SUCCEED) {
     216           0 :                 if (verbose) {
     217           0 :                         fprintf(stderr, "Context Alloc failed!\n");
     218             :                 }
     219             :                 return ret;
     220             :         }
     221             : 
     222             : #ifdef TDS_STATIC_CAST
     223             :         /* Force default date format, some tests rely on it */
     224        1040 :         tds_ctx = (TDSCONTEXT *) (*ctx)->tds_ctx;
     225        1040 :         if (tds_ctx && tds_ctx->locale && tds_ctx->locale->datetime_fmt) {
     226        1040 :                 free(tds_ctx->locale->datetime_fmt);
     227        1040 :                 tds_ctx->locale->datetime_fmt = strdup("%b %d %Y %I:%M%p");
     228             :         }
     229             : #endif
     230             : 
     231        1040 :         ret = ct_init(*ctx, CS_VERSION_100);
     232        1040 :         if (ret != CS_SUCCEED) {
     233           0 :                 if (verbose) {
     234           0 :                         fprintf(stderr, "Library Init failed!\n");
     235             :                 }
     236             :                 return ret;
     237             :         }
     238        1040 :         if ((ret = ct_callback(*ctx, NULL, CS_SET, CS_CLIENTMSG_CB,
     239             :                                (CS_VOID*) clientmsg_cb)) != CS_SUCCEED) {
     240           0 :                 fprintf(stderr, "ct_callback() failed\n");
     241           0 :                 return ret;
     242             :         }
     243        1040 :         if ((ret = ct_callback(*ctx, NULL, CS_SET, CS_SERVERMSG_CB, servermsg_cb)) != CS_SUCCEED) {
     244           0 :                 fprintf(stderr, "ct_callback() failed\n");
     245           0 :                 return ret;
     246             :         }
     247        1040 :         ret = ct_con_alloc(*ctx, conn);
     248        1040 :         if (ret != CS_SUCCEED) {
     249           0 :                 if (verbose) {
     250           0 :                         fprintf(stderr, "Connect Alloc failed!\n");
     251             :                 }
     252             :                 return ret;
     253             :         }
     254        1040 :         ret = ct_con_props(*conn, CS_SET, CS_USERNAME, USER, CS_NULLTERM, NULL);
     255        1040 :         if (ret != CS_SUCCEED) {
     256           0 :                 if (verbose) {
     257           0 :                         fprintf(stderr, "ct_con_props() SET USERNAME failed!\n");
     258             :                 }
     259             :                 return ret;
     260             :         }
     261        1040 :         ret = ct_con_props(*conn, CS_SET, CS_PASSWORD, PASSWORD, CS_NULLTERM, NULL);
     262        1040 :         if (ret != CS_SUCCEED) {
     263           0 :                 if (verbose) {
     264           0 :                         fprintf(stderr, "ct_con_props() SET PASSWORD failed!\n");
     265             :                 }
     266             :                 return ret;
     267             :         }
     268             : 
     269        1040 :         printf("connecting as %s to %s.%s\n", USER, SERVER, DATABASE);
     270             : 
     271        1040 :         ret = ct_connect(*conn, SERVER, CS_NULLTERM);
     272        1040 :         if (ret != CS_SUCCEED) {
     273           0 :                 if (verbose) {
     274           0 :                         fprintf(stderr, "Connection failed!\n");
     275             :                 }
     276           0 :                 ct_con_drop(*conn);
     277           0 :                 *conn = NULL;
     278           0 :                 cs_ctx_drop(*ctx);
     279           0 :                 *ctx = NULL;
     280           0 :                 return ret;
     281             :         }
     282        1040 :         ret = ct_cmd_alloc(*conn, cmd);
     283        1040 :         if (ret != CS_SUCCEED) {
     284           0 :                 if (verbose) {
     285           0 :                         fprintf(stderr, "Command Alloc failed!\n");
     286             :                 }
     287           0 :                 ct_con_drop(*conn);
     288           0 :                 *conn = NULL;
     289           0 :                 cs_ctx_drop(*ctx);
     290           0 :                 *ctx = NULL;
     291           0 :                 return ret;
     292             :         }
     293             : 
     294        1040 :         sprintf(query, "use %s", DATABASE);
     295             : 
     296        1040 :         ret = run_command(*cmd, query);
     297        1040 :         if (ret != CS_SUCCEED)
     298             :                 return ret;
     299             : 
     300        1040 :         return CS_SUCCEED;
     301             : }
     302             : 
     303             : 
     304             : CS_RETCODE
     305        1040 : try_ctlogout(CS_CONTEXT * ctx, CS_CONNECTION * conn, CS_COMMAND * cmd, int verbose)
     306             : {
     307             :         CS_RETCODE ret;
     308             : 
     309        1040 :         ret = ct_cancel(conn, NULL, CS_CANCEL_ALL);
     310        1040 :         if (ret != CS_SUCCEED) {
     311           0 :                 if (verbose) {
     312           0 :                         fprintf(stderr, "ct_cancel() failed!\n");
     313             :                 }
     314             :                 return ret;
     315             :         }
     316        1040 :         ct_cmd_drop(cmd);
     317        1040 :         ct_close(conn, CS_UNUSED);
     318        1040 :         ct_con_drop(conn);
     319        1040 :         ct_exit(ctx, CS_UNUSED);
     320        1040 :         cs_ctx_drop(ctx);
     321             : 
     322        1040 :         return CS_SUCCEED;
     323             : }
     324             : 
     325             : /* Run commands from which we expect no results returned */
     326             : CS_RETCODE
     327        1884 : run_command(CS_COMMAND * cmd, const char *sql)
     328             : {
     329             :         CS_RETCODE ret, results_ret;
     330             :         CS_INT result_type;
     331             : 
     332        1884 :         if (cmd == NULL) {
     333             :                 return CS_FAIL;
     334             :         }
     335             : 
     336        1884 :         ret = ct_command(cmd, CS_LANG_CMD, sql, CS_NULLTERM, CS_UNUSED);
     337        1884 :         if (ret != CS_SUCCEED) {
     338           0 :                 fprintf(stderr, "ct_command() failed\n");
     339           0 :                 return ret;
     340             :         }
     341        1884 :         ret = ct_send(cmd);
     342        1884 :         if (ret != CS_SUCCEED) {
     343           2 :                 fprintf(stderr, "ct_send() failed\n");
     344           2 :                 return ret;
     345             :         }
     346        5766 :         while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
     347        3884 :                 switch ((int) result_type) {
     348             :                 case CS_CMD_SUCCEED:
     349             :                         break;
     350             :                 case CS_CMD_DONE:
     351             :                         break;
     352          46 :                 case CS_CMD_FAIL:
     353          46 :                         fprintf(stderr, "ct_results() result_type CS_CMD_FAIL.\n");
     354             :                         /* return CS_FAIL; */
     355          46 :                         break;
     356           0 :                 default:
     357           0 :                         fprintf(stderr, "ct_results() unexpected result_type.\n");
     358           0 :                         return CS_FAIL;
     359             :                 }
     360             :         }
     361        1882 :         switch ((int) results_ret) {
     362             :         case CS_END_RESULTS:
     363             :                 break;
     364           0 :         case CS_FAIL:
     365           0 :                 fprintf(stderr, "ct_results() failed.\n");
     366           0 :                 return CS_FAIL;
     367             :                 break;
     368           0 :         default:
     369           0 :                 fprintf(stderr, "ct_results() unexpected return.\n");
     370           0 :                 return CS_FAIL;
     371             :         }
     372             : 
     373             :         return CS_SUCCEED;
     374             : }
     375             : 
     376             : CS_INT
     377          24 : cslibmsg_cb(CS_CONTEXT * connection, CS_CLIENTMSG * errmsg)
     378             : {
     379          24 :         cslibmsg_cb_invoked++;
     380          24 :         fprintf(stderr, "\nCS-Library Message:\n");
     381          96 :         fprintf(stderr, "number %d layer %d origin %d severity %d number %d\n",
     382             :                 errmsg->msgnumber,
     383          24 :                 CS_LAYER(errmsg->msgnumber),
     384          72 :                 CS_ORIGIN(errmsg->msgnumber), CS_SEVERITY(errmsg->msgnumber), CS_NUMBER(errmsg->msgnumber));
     385          24 :         fprintf(stderr, "msgstring: %s\n", errmsg->msgstring);
     386          24 :         fprintf(stderr, "osstring: %s\n", (errmsg->osstringlen > 0)
     387             :                 ? errmsg->osstring : "(null)");
     388          24 :         return CS_SUCCEED;
     389             : }
     390             : 
     391             : 
     392             : 
     393             : CS_RETCODE
     394          16 : clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg)
     395             : {
     396          16 :         clientmsg_cb_invoked++;
     397          16 :         fprintf(stderr, "\nOpen Client Message:\n");
     398          64 :         fprintf(stderr, "number %d layer %d origin %d severity %d number %d\n",
     399             :                 errmsg->msgnumber,
     400          16 :                 CS_LAYER(errmsg->msgnumber),
     401          48 :                 CS_ORIGIN(errmsg->msgnumber), CS_SEVERITY(errmsg->msgnumber), CS_NUMBER(errmsg->msgnumber));
     402          16 :         fprintf(stderr, "msgstring: %s\n", errmsg->msgstring);
     403          16 :         fprintf(stderr, "osstring: %s\n", (errmsg->osstringlen > 0)
     404             :                 ? errmsg->osstring : "(null)");
     405          16 :         return CS_SUCCEED;
     406             : }
     407             : 
     408             : CS_RETCODE
     409        3180 : servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
     410             : {
     411        3180 :         servermsg_cb_invoked++;
     412             : 
     413        3180 :         if (srvmsg->msgnumber == 5701 || srvmsg->msgnumber == 5703) {
     414        2860 :                 fprintf(stderr, "%s\n", srvmsg->text);
     415        2860 :                 return CS_SUCCEED;
     416             :         }
     417             : 
     418         640 :         fprintf(stderr, "%s Message %d severity %d state %d line %d:\n",
     419         320 :                 srvmsg->svrnlen > 0? srvmsg->svrname : "Server",
     420             :                 srvmsg->msgnumber, srvmsg->severity, srvmsg->state, srvmsg->line);
     421         320 :         if (srvmsg->proclen > 0)
     422           8 :                 fprintf(stderr, "proc %s: ", srvmsg->proc);
     423         320 :         fprintf(stderr, "\t\"%s\"\n", srvmsg->text);
     424             : 
     425         320 :         return CS_SUCCEED;
     426             : }
     427             : 
     428             : const char *
     429         380 : res_type_str(CS_RETCODE ret)
     430             : {
     431             :         static char str[64];
     432             : 
     433             : #define S(s) case s: return #s;
     434         380 :         switch ((int) ret) {
     435             :         S(CS_ROW_RESULT)
     436           0 :         S(CS_PARAM_RESULT)
     437          64 :         S(CS_STATUS_RESULT)
     438           0 :         S(CS_MSG_RESULT)
     439          64 :         S(CS_CMD_SUCCEED)
     440         142 :         S(CS_CMD_DONE)
     441           0 :         S(CS_CMD_FAIL)
     442          24 :         S(CS_COMPUTE_RESULT)
     443             : #undef S
     444             :         }
     445             : 
     446           0 :         sprintf(str, "?? (%d)", (int) ret);
     447           0 :         return str;
     448             : }

Generated by: LCOV version 1.13