LCOV - code coverage report
Current view: top level - clients/odbc/driver - SQLConnect.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 96 140 68.6 %
Date: 2021-10-13 02:24:04 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /*
       2             :  * This Source Code Form is subject to the terms of the Mozilla Public
       3             :  * License, v. 2.0.  If a copy of the MPL was not distributed with this
       4             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       5             :  *
       6             :  * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V.
       7             :  */
       8             : 
       9             : /*
      10             :  * This code was created by Peter Harvey (mostly during Christmas 98/99).
      11             :  * This code is LGPL. Please ensure that this message remains in future
      12             :  * distributions and uses of this code (thats about all I get out of it).
      13             :  * - Peter Harvey pharvey@codebydesign.com
      14             :  *
      15             :  * This file has been modified for the MonetDB project.  See the file
      16             :  * Copyright in this directory for more information.
      17             :  */
      18             : 
      19             : /**********************************************************************
      20             :  * SQLConnect()
      21             :  * CLI Compliance: ISO 92
      22             :  *
      23             :  * Author: Martin van Dinther, Sjoerd Mullender
      24             :  * Date  : 30 aug 2002
      25             :  *
      26             :  **********************************************************************/
      27             : 
      28             : #include "ODBCGlobal.h"
      29             : #include "ODBCDbc.h"
      30             : #include "ODBCUtil.h"
      31             : #include <time.h>
      32             : 
      33             : #ifdef HAVE_ODBCINST_H
      34             : #include <odbcinst.h>
      35             : #endif
      36             : 
      37             : #ifndef HAVE_SQLGETPRIVATEPROFILESTRING
      38             : #define SQLGetPrivateProfileString(section,entry,default,buffer,bufferlen,filename)     ((int) strcpy_len(buffer,default,bufferlen))
      39             : #endif
      40             : 
      41             : static void
      42           2 : set_timezone(Mapi mid)
      43             : {
      44             :         char buf[128];
      45             :         time_t t, lt, gt;
      46             :         struct tm *tmp;
      47             :         long tzone;
      48             :         MapiHdl hdl;
      49             : 
      50             :         /* figure out our current timezone */
      51           2 :         t = time(NULL);
      52           2 :         tmp = gmtime(&t);
      53           2 :         gt = mktime(tmp);
      54           2 :         tmp = localtime(&t);
      55           2 :         lt = mktime(tmp);
      56           2 :         tzone = (long) (gt - lt);
      57           2 :         if (tzone < 0)
      58           2 :                 snprintf(buf, sizeof(buf),
      59             :                          "SET TIME ZONE INTERVAL '+%02ld:%02ld' HOUR TO MINUTE",
      60           2 :                          -tzone / 3600, (-tzone % 3600) / 60);
      61             :         else
      62           0 :                 snprintf(buf, sizeof(buf),
      63             :                          "SET TIME ZONE INTERVAL '-%02ld:%02ld' HOUR TO MINUTE",
      64           0 :                          tzone / 3600, (tzone % 3600) / 60);
      65           2 :         if ((hdl = mapi_query(mid, buf)) != NULL)
      66           2 :                 mapi_close_handle(hdl);
      67           2 : }
      68             : 
      69             : static void
      70           2 : get_serverinfo(ODBCDbc *dbc)
      71             : {
      72             :         MapiHdl hdl;
      73             :         char *n, *v;
      74             : 
      75           2 :         if ((hdl = mapi_query(dbc->mid, "select name, value from sys.env() where name in ('monet_version', 'gdk_dbname')")) == NULL)
      76             :                 return;
      77           6 :         while (mapi_fetch_row(hdl)) {
      78           4 :                 n = mapi_fetch_field(hdl, 0);
      79           4 :                 v = mapi_fetch_field(hdl, 1);
      80           4 :                 if (strcmp(n, "monet_version") == 0) {
      81           2 :                         sscanf(v, "%hd.%hd.%hd",
      82             :                                &dbc->major, &dbc->minor, &dbc->patch);
      83             :                 } else {
      84           2 :                         assert(strcmp(n, "gdk_dbname") == 0);
      85           2 :                         assert(dbc->dbname == NULL ||
      86             :                                strcmp(dbc->dbname, v) == 0);
      87           2 :                         if (dbc->dbname)
      88           2 :                                 free(dbc->dbname);
      89           2 :                         dbc->dbname = strdup(v);
      90             :                 }
      91             :         }
      92           2 :         mapi_close_handle(hdl);
      93           2 :         if ((hdl = mapi_query(dbc->mid, "select id from sys._tables where name = 'comments' and schema_id = (select id from sys.schemas where name = 'sys')")) == NULL)
      94             :                 return;
      95             :         n = NULL;
      96           4 :         while (mapi_fetch_row(hdl)) {
      97           2 :                 n = mapi_fetch_field(hdl, 0);
      98             :         }
      99           2 :         dbc->has_comment = n != NULL;
     100           2 :         mapi_close_handle(hdl);
     101             : }
     102             : 
     103             : SQLRETURN
     104           2 : MNDBConnect(ODBCDbc *dbc,
     105             :             const SQLCHAR *ServerName,
     106             :             SQLSMALLINT NameLength1,
     107             :             const SQLCHAR *UserName,
     108             :             SQLSMALLINT NameLength2,
     109             :             const SQLCHAR *Authentication,
     110             :             SQLSMALLINT NameLength3,
     111             :             const char *host,
     112             :             int port,
     113             :             const char *catalog)
     114             : {
     115             :         SQLRETURN rc = SQL_SUCCESS;
     116             :         char *dsn = NULL;
     117             :         char uid[32];
     118             :         char pwd[32];
     119             :         char buf[256];
     120             :         char db[32];
     121             :         char *s;
     122             :         int n;
     123             :         Mapi mid;
     124             : 
     125             :         /* check connection state, should not be connected */
     126           2 :         if (dbc->Connected) {
     127             :                 /* Connection name in use */
     128           0 :                 addDbcError(dbc, "08002", NULL, 0);
     129           0 :                 return SQL_ERROR;
     130             :         }
     131             : 
     132             :         /* convert input string parameters to normal null terminated C strings */
     133           2 :         fixODBCstring(ServerName, NameLength1, SQLSMALLINT,
     134             :                       addDbcError, dbc, return SQL_ERROR);
     135           2 :         if (NameLength1 > 0) {
     136           2 :                 dsn = dupODBCstring(ServerName, (size_t) NameLength1);
     137           2 :                 if (dsn == NULL) {
     138             :                         /* Memory allocation error */
     139           0 :                         addDbcError(dbc, "HY001", NULL, 0);
     140           0 :                         return SQL_ERROR;
     141             :                 }
     142             :         }
     143             : 
     144             : #ifdef ODBCDEBUG
     145           2 :         if ((ODBCdebug == NULL || *ODBCdebug == 0) && dsn && *dsn) {
     146             :                 char logfile[2048];
     147           2 :                 n = SQLGetPrivateProfileString(dsn, "logfile", "",
     148             :                                                logfile, sizeof(logfile),
     149             :                                                "odbc.ini");
     150           2 :                 if (n > 0) {
     151           0 :                         if (ODBCdebug)
     152           0 :                                 free((void *) ODBCdebug); /* discard const */
     153           0 :                         ODBCdebug = strdup(logfile);
     154             :                 }
     155             :         }
     156             : #endif
     157             : 
     158           2 :         if (dsn && *dsn)
     159           2 :                 n = SQLGetPrivateProfileString(dsn, "uid", "monetdb",
     160             :                                                uid, sizeof(uid), "odbc.ini");
     161             :         else
     162             :                 n = 0;
     163           2 :         fixODBCstring(UserName, NameLength2, SQLSMALLINT,
     164             :                       addDbcError, dbc, if (dsn) free(dsn); return SQL_ERROR);
     165           2 :         if (n == 0 && NameLength2 == 0) {
     166           0 :                 if (dsn)
     167           0 :                         free(dsn);
     168             :                 /* Invalid authorization specification */
     169           0 :                 addDbcError(dbc, "28000", NULL, 0);
     170           0 :                 return SQL_ERROR;
     171             :         }
     172           2 :         if (NameLength2 > 0) {
     173           2 :                 if ((size_t)NameLength2 >= sizeof(uid))
     174             :                         NameLength2 = sizeof(uid) - 1;
     175           2 :                 strncpy(uid, (char *) UserName, NameLength2);
     176           2 :                 uid[NameLength2] = 0;
     177             :         }
     178           2 :         if (dsn && *dsn)
     179           2 :                 n = SQLGetPrivateProfileString(dsn, "pwd", "monetdb",
     180             :                                                pwd, sizeof(pwd), "odbc.ini");
     181             :         else
     182             :                 n = 0;
     183           2 :         fixODBCstring(Authentication, NameLength3, SQLSMALLINT,
     184             :                       addDbcError, dbc, if (dsn) free(dsn); return SQL_ERROR);
     185           2 :         if (n == 0 && NameLength3 == 0) {
     186           0 :                 if (dsn)
     187           0 :                         free(dsn);
     188             :                 /* Invalid authorization specification */
     189           0 :                 addDbcError(dbc, "28000", NULL, 0);
     190           0 :                 return SQL_ERROR;
     191             :         }
     192           2 :         if (NameLength3 > 0) {
     193           2 :                 if ((size_t)NameLength3 >= sizeof(pwd))
     194             :                         NameLength3 = sizeof(pwd) - 1;
     195           2 :                 strncpy(pwd, (char *) Authentication, NameLength3);
     196           2 :                 pwd[NameLength3] = 0;
     197             :         }
     198             : 
     199           2 :         if (catalog == NULL || *catalog == 0) {
     200           2 :                 catalog = dbc->dbname;
     201             :         }
     202           2 :         if (catalog == NULL || *catalog == 0) {
     203           2 :                 if (dsn && *dsn) {
     204           2 :                         n = SQLGetPrivateProfileString(dsn, "database", "", db,
     205             :                                                        sizeof(db), "odbc.ini");
     206           2 :                         if (n > 0)
     207             :                                 catalog = db;
     208             :                 }
     209             :         }
     210           2 :         if (catalog && !*catalog)
     211             :                 catalog = NULL;
     212             : 
     213           2 :         if (port == 0 && (s = getenv("MAPIPORT")) != NULL)
     214             :                 port = atoi(s);
     215           2 :         if (port == 0 && dsn && *dsn) {
     216           0 :                 n = SQLGetPrivateProfileString(dsn, "port", MAPI_PORT_STR,
     217             :                                                buf, sizeof(buf), "odbc.ini");
     218           0 :                 if (n > 0)
     219             :                         port = atoi(buf);
     220             :         }
     221           2 :         if (port == 0)
     222             :                 port = MAPI_PORT;
     223             : 
     224           2 :         if (host == NULL || *host == 0) {
     225             :                 host = "localhost";
     226           2 :                 if (dsn && *dsn) {
     227           2 :                         n = SQLGetPrivateProfileString(dsn, "host", "localhost",
     228             :                                                        buf, sizeof(buf),
     229             :                                                        "odbc.ini");
     230           2 :                         if (n > 0)
     231             :                                 host = buf;
     232             :                 }
     233             :         }
     234             : 
     235             : #ifdef ODBCDEBUG
     236           2 :         ODBCLOG("SQLConnect: DSN=%s UID=%s PWD=%s host=%s port=%d database=%s\n",
     237             :                 dsn ? dsn : "(null)", uid, pwd, host, port,
     238             :                 catalog ? catalog : "(null)");
     239             : #endif
     240             : 
     241             :         /* connect to a server on host via port */
     242             :         /* FIXME: use dbname/catalog from ODBC connect string/options here */
     243           2 :         mid = mapi_connect(host, port, uid, pwd, "sql", catalog);
     244           2 :         if (mid == NULL || mapi_error(mid)) {
     245             :                 /* Client unable to establish connection */
     246           0 :                 addDbcError(dbc, "08001", NULL, 0);
     247             :                 rc = SQL_ERROR;
     248             :                 /* clean up */
     249           0 :                 if (mid)
     250           0 :                         mapi_destroy(mid);
     251           0 :                 if (dsn != NULL)
     252           0 :                         free(dsn);
     253             :         } else {
     254             :                 /* store internal information and clean up buffers */
     255           2 :                 dbc->Connected = true;
     256           2 :                 dbc->mid = mid;
     257           2 :                 if (dbc->dsn != NULL)
     258           0 :                         free(dbc->dsn);
     259           2 :                 dbc->dsn = dsn;
     260           2 :                 if (dbc->uid != NULL)
     261           0 :                         free(dbc->uid);
     262           2 :                 dbc->uid = strdup(uid);
     263           2 :                 if (dbc->pwd != NULL)
     264           0 :                         free(dbc->pwd);
     265           2 :                 dbc->pwd = strdup(pwd);
     266           2 :                 if (dbc->host)
     267           0 :                         free(dbc->host);
     268           2 :                 dbc->host = strdup(host);
     269           2 :                 if (catalog)    /* dup before dbname is freed */
     270           2 :                         catalog = strdup(catalog);
     271           2 :                 if (dbc->dbname != NULL)
     272           0 :                         free(dbc->dbname);
     273           2 :                 dbc->dbname = (char *) catalog; /* discard const */
     274           2 :                 mapi_setAutocommit(mid, dbc->sql_attr_autocommit == SQL_AUTOCOMMIT_ON);
     275           2 :                 set_timezone(mid);
     276           2 :                 get_serverinfo(dbc);
     277           2 :                 mapi_set_size_header(mid, true);
     278             :                 /* set timeout after we're connected */
     279           2 :                 mapi_timeout(mid, dbc->sql_attr_connection_timeout * 1000);
     280             :         }
     281             : 
     282             :         return rc;
     283             : }
     284             : 
     285             : SQLRETURN SQL_API
     286             : SQLConnect(SQLHDBC ConnectionHandle,
     287             :            SQLCHAR *ServerName,
     288             :            SQLSMALLINT NameLength1,
     289             :            SQLCHAR *UserName,
     290             :            SQLSMALLINT NameLength2,
     291             :            SQLCHAR *Authentication,
     292             :            SQLSMALLINT NameLength3)
     293             : {
     294             : #ifdef ODBCDEBUG
     295           2 :         ODBCLOG("SQLConnect %p\n", ConnectionHandle);
     296             : #endif
     297             : 
     298           2 :         if (!isValidDbc((ODBCDbc *) ConnectionHandle))
     299             :                 return SQL_INVALID_HANDLE;
     300             : 
     301           2 :         clearDbcErrors((ODBCDbc *) ConnectionHandle);
     302             : 
     303           2 :         return MNDBConnect((ODBCDbc *) ConnectionHandle,
     304             :                            ServerName, NameLength1,
     305             :                            UserName, NameLength2,
     306             :                            Authentication, NameLength3,
     307             :                            NULL, 0, NULL);
     308             : }
     309             : 
     310             : SQLRETURN SQL_API
     311             : SQLConnectA(SQLHDBC ConnectionHandle,
     312             :             SQLCHAR *ServerName,
     313             :             SQLSMALLINT NameLength1,
     314             :             SQLCHAR *UserName,
     315             :             SQLSMALLINT NameLength2,
     316             :             SQLCHAR *Authentication,
     317             :             SQLSMALLINT NameLength3)
     318             : {
     319           0 :         return SQLConnect(ConnectionHandle,
     320             :                           ServerName, NameLength1,
     321             :                           UserName, NameLength2,
     322             :                           Authentication, NameLength3);
     323             : }
     324             : 
     325             : SQLRETURN SQL_API
     326             : SQLConnectW(SQLHDBC ConnectionHandle,
     327             :             SQLWCHAR *ServerName,
     328             :             SQLSMALLINT NameLength1,
     329             :             SQLWCHAR *UserName,
     330             :             SQLSMALLINT NameLength2,
     331             :             SQLWCHAR *Authentication,
     332             :             SQLSMALLINT NameLength3)
     333             : {
     334             :         SQLCHAR *ds = NULL, *uid = NULL, *pwd = NULL;
     335             :         SQLRETURN rc = SQL_ERROR;
     336             :         ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
     337             : 
     338             : #ifdef ODBCDEBUG
     339           0 :         ODBCLOG("SQLConnectW %p\n", ConnectionHandle);
     340             : #endif
     341             : 
     342           0 :         if (!isValidDbc(dbc))
     343             :                 return SQL_INVALID_HANDLE;
     344             : 
     345           0 :         clearDbcErrors(dbc);
     346             : 
     347           0 :         fixWcharIn(ServerName, NameLength1, SQLCHAR, ds,
     348             :                    addDbcError, dbc, goto bailout);
     349           0 :         fixWcharIn(UserName, NameLength2, SQLCHAR, uid,
     350             :                    addDbcError, dbc, goto bailout);
     351           0 :         fixWcharIn(Authentication, NameLength3, SQLCHAR, pwd,
     352             :                    addDbcError, dbc, goto bailout);
     353             : 
     354           0 :         rc = MNDBConnect(dbc,
     355             :                          ds, SQL_NTS,
     356             :                          uid, SQL_NTS,
     357             :                          pwd, SQL_NTS,
     358             :                          NULL, 0, NULL);
     359             : 
     360           0 :       bailout:
     361           0 :         if (ds)
     362           0 :                 free(ds);
     363           0 :         if (uid)
     364           0 :                 free(uid);
     365           0 :         if (pwd)
     366           0 :                 free(pwd);
     367             :         return rc;
     368             : }

Generated by: LCOV version 1.14