LCOV - code coverage report
Current view: top level - src/odbc/unittests - connect.c (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 59 67 88.1 %
Date: 2026-07-19 14:02:14 Functions: 2 2 100.0 %

          Line data    Source code
       1             : #include "common.h"
       2             : 
       3             : 
       4             : static void init_connect(void);
       5             : 
       6             : static void
       7          48 : init_connect(void)
       8             : {
       9          48 :         CHKAllocEnv(&odbc_env, "S");
      10          48 :         CHKAllocConnect(&odbc_conn, "S");
      11          48 : }
      12             : 
      13          10 : TEST_MAIN()
      14             : {
      15             :         char tmp[1024*4];
      16             :         SQLSMALLINT len;
      17          10 :         int succeeded = 0;
      18             :         bool is_freetds;
      19             :         bool is_ms;
      20             :         SQLRETURN rc;
      21             : 
      22          10 :         odbc_use_version3 = false;
      23             : 
      24             :         /* NOTE: In Windows, this function will copy the data from PWD into
      25             :          * a registry entry HKCU\Software\ODBC\ODBC.INI\{servername}
      26             :          */
      27          10 :         if (odbc_read_login_info())
      28           0 :                 exit(1);
      29             : 
      30             : #ifndef _WIN32
      31             :         /*
      32             :          * prepare our odbcinst.ini 
      33             :          * is better to do it before connect cause uniODBC cache INIs
      34             :          * the name must be odbcinst.ini cause unixODBC accept only this name
      35             :          *
      36             :          * In Windows, odbcinst.ini text file is not used - you will need to
      37             :          * configure FreeTDS via the Odbcinst.ini registry key.
      38             :          */
      39          10 :         if (common_pwd.driver[0]) {
      40          10 :                 FILE *f = fopen("odbcinst.ini", "w");
      41             : 
      42          10 :                 if (f) {
      43          10 :                         fprintf(f, "[FreeTDS]\nDriver = %s\n", common_pwd.driver);
      44          10 :                         fclose(f);
      45             :                         /* force iODBC */
      46          10 :                         setenv("ODBCINSTINI", "./odbcinst.ini", 1);
      47          10 :                         setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
      48             :                         /* force unixODBC (only directory) */
      49          10 :                         setenv("ODBCSYSINI", ".", 1);
      50             :                 }
      51             :         }
      52             : #endif
      53             :         /* Connect using SQLConnect() with Server, User and Password from PWD file
      54             :          * NOTE: In Windows this looks up DSN in HKCU\Software\ODBC\ODBC.INI, with fallback to HKLM
      55             :          */
      56          10 :         printf("SQLConnect(server=%s, ...) connect..\n", common_pwd.server);
      57          10 :         odbc_connect();
      58          10 :         is_freetds = odbc_driver_is_freetds();
      59          10 :         is_ms = odbc_db_is_microsoft();
      60          10 :         odbc_disconnect();
      61          10 :         ++succeeded;
      62             : 
      63          10 :         if (!is_freetds) {
      64           0 :                 printf("Driver is not FreeTDS, exiting\n");
      65           0 :                 odbc_test_skipped();
      66           0 :                 return 0;
      67             :         }
      68             : 
      69             :         /* try connect string with using DSN= (should behave the same as SQLConnect)
      70             :          */
      71          10 :         printf("SQLDriverConnect(DSN=%s;...)\n", common_pwd.server);
      72          10 :         init_connect();
      73          10 :         sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", common_pwd.server,
      74             :                 common_pwd.user, common_pwd.password, common_pwd.database);
      75          10 :         CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp)/sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "SI");
      76          10 :         odbc_disconnect();
      77          10 :         ++succeeded;
      78             : 
      79             :         /* try connect string using DRIVER=  (this means to look up DRIVER name in ODBCINST.INI) */
      80          10 :         printf("SQLDriverConnect(DRIVER=FreeTDS;SERVERNAME=%s;...)\n", common_pwd.server);
      81             : #ifndef _WIN32
      82          10 :         printf("odbcinst.ini must exist and contain an entry [FreeTDS].\n");
      83             : #endif
      84             :         /* this is expected to work with unixODBC, and Windows.
      85             :          * NOTE: This will connect to whatever driver you have configured in ODBCINST.INI,
      86             :          * not the actual driver we just built and are testing. However for this test,
      87             :          * that's OK as here we are testing connecting to a driver, not testing that driver.
      88             :          */
      89          10 :         init_connect();
      90          10 :         sprintf(tmp,
      91             :                 "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;",
      92             :                 common_pwd.server, common_pwd.user, common_pwd.password, common_pwd.database);
      93          10 :         rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp) / sizeof(SQLTCHAR), &len,
      94             :                               SQL_DRIVER_NOPROMPT, "SIE");
      95          10 :         if (rc == SQL_ERROR) {
      96           0 :                 printf("Unable to open data source (ret=%d)\n", rc);
      97             : #ifdef _WIN32
      98             :                 printf("Try from admin command prompt:\n"
      99             :                        "\todbcconf /A {INSTALLDRIVER \"FreeTDS|Driver=C:\\Program Files(x86)\\FreeTDS\\bin\\tdsodbc.dll\"}\n"
     100             :                        "(replace path with your installation path for tdsodbc.dll if necessary)\n");
     101             : #endif
     102             :         } else {
     103             :                 ++succeeded;
     104             :         }
     105          10 :         odbc_disconnect();
     106             : 
     107             :         /* this is expected to work with iODBC (passing full path to driver)
     108             :          */
     109          10 :         if (common_pwd.driver[0]) {
     110          10 :                 printf("SQLDriverConnect(DRIVER=%s;...)\n", common_pwd.driver);
     111          10 :                 init_connect();
     112          10 :                 sprintf(tmp,
     113             :                         "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;",
     114             :                         common_pwd.driver, common_pwd.server, common_pwd.user, common_pwd.password, common_pwd.database);
     115          10 :                 rc = CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp) / sizeof(SQLTCHAR), &len,
     116             :                                       SQL_DRIVER_NOPROMPT, "SIE");
     117          10 :                 if (rc == SQL_ERROR) {
     118           0 :                         printf("Unable to open data source via iODBC syntax (ret=%d)\n", rc);
     119             :                 } else {
     120          10 :                         ++succeeded;
     121             :                 }
     122          10 :                 odbc_disconnect();
     123             :         }
     124             : 
     125          10 :         if (is_ms) {
     126             :                 char app_name[130];
     127             : 
     128           8 :                 memset(app_name, 'a', sizeof(app_name));
     129           8 :                 app_name[sizeof(app_name) - 1] = 0;
     130             : 
     131             :                 /* Try passing very long APP string.
     132             :                  * The server is supposed to fail the connection if
     133             :                  * this string is too long, make sure we truncate it.
     134             :                  */
     135           8 :                 printf("connect string DSN connect with a long APP..\n");
     136           8 :                 init_connect();
     137           8 :                 sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;APP=%s",
     138             :                         common_pwd.server, common_pwd.user, common_pwd.password, common_pwd.database, app_name);
     139           8 :                 CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp) / sizeof(SQLTCHAR), &len,
     140             :                                  SQL_DRIVER_NOPROMPT, "SI");
     141           8 :                 odbc_disconnect();
     142             :         }
     143             : 
     144             :         /* test invalid string, it should not leak memory */
     145          10 :         init_connect();
     146          10 :         sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;test={unfinished",
     147             :                 common_pwd.server, common_pwd.user, common_pwd.password, common_pwd.database);
     148          10 :         CHKDriverConnect(NULL, T(tmp), SQL_NTS, (SQLTCHAR *) tmp, sizeof(tmp) / sizeof(SQLTCHAR), &len, SQL_DRIVER_NOPROMPT, "E");
     149          10 :         odbc_disconnect();
     150             : 
     151             :         /* at least one should success.. */
     152          10 :         if (succeeded < 3) {
     153           0 :                 ODBC_REPORT_ERROR("Too few successes");
     154           0 :                 exit(1);
     155             :         }
     156             : 
     157          10 :         printf("Done.\n");
     158          10 :         return 0;
     159             : }

Generated by: LCOV version 1.13