Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * This code was created by Peter Harvey (mostly during Christmas 98/99).
15 : * This code is LGPL. Please ensure that this message remains in future
16 : * distributions and uses of this code (thats about all I get out of it).
17 : * - Peter Harvey pharvey@codebydesign.com
18 : *
19 : * This file has been modified for the MonetDB project. See the file
20 : * Copyright in this directory for more information.
21 : */
22 :
23 : /**********************************************************************
24 : * SQLBrowseConnect()
25 : * CLI Compliance: ODBC (Microsoft)
26 : *
27 : * Author: Martin van Dinther, Sjoerd Mullender
28 : * Date : 30 Aug 2002
29 : *
30 : **********************************************************************/
31 :
32 : #include "ODBCGlobal.h"
33 : #include "ODBCDbc.h"
34 : #include "ODBCUtil.h"
35 : #ifdef HAVE_STRINGS_H
36 : #include <strings.h> /* strcasecmp */
37 : #endif
38 :
39 : #ifdef HAVE_ODBCINST_H
40 : #include <odbcinst.h>
41 : #endif
42 :
43 : #ifndef HAVE_SQLGETPRIVATEPROFILESTRING
44 : #define SQLGetPrivateProfileString(section,entry,default,buffer,bufferlen,filename) ((int) strcpy_len(buffer,default,bufferlen))
45 : #endif
46 :
47 :
48 : static SQLRETURN
49 0 : MNDBBrowseConnect(ODBCDbc *dbc,
50 : const SQLCHAR *InConnectionString,
51 : SQLSMALLINT StringLength1,
52 : SQLCHAR *OutConnectionString,
53 : SQLSMALLINT BufferLength,
54 : SQLSMALLINT *StringLength2Ptr)
55 : {
56 0 : char *key, *attr;
57 0 : char *dsn, *uid, *pwd, *host, *dbname;
58 0 : int port, mapToLongVarchar;
59 0 : SQLSMALLINT len = 0;
60 0 : char buf[1024];
61 0 : int n;
62 0 : SQLRETURN rc;
63 : #ifdef ODBCDEBUG
64 0 : bool allocated = false;
65 : #endif
66 :
67 0 : fixODBCstring(InConnectionString, StringLength1, SQLSMALLINT, addDbcError, dbc, return SQL_ERROR);
68 :
69 : #ifdef ODBCDEBUG
70 0 : ODBCLOG(" \"%.*s\"\n", (int) StringLength1, (char*) InConnectionString);
71 : #endif
72 :
73 : /* check connection state, should not be connected */
74 0 : if (dbc->Connected) {
75 : /* Connection name in use */
76 0 : addDbcError(dbc, "08002", NULL, 0);
77 0 : return SQL_ERROR;
78 : }
79 :
80 0 : dsn = dbc->dsn ? strdup(dbc->dsn) : NULL;
81 0 : uid = dbc->uid ? strdup(dbc->uid) : NULL;
82 0 : pwd = dbc->pwd ? strdup(dbc->pwd) : NULL;
83 0 : host = dbc->host ? strdup(dbc->host) : NULL;
84 0 : port = dbc->port;
85 0 : dbname = dbc->dbname ? strdup(dbc->dbname) : NULL;
86 0 : mapToLongVarchar = dbc->mapToLongVarchar;
87 :
88 0 : while ((n = ODBCGetKeyAttr(&InConnectionString, &StringLength1, &key, &attr)) > 0) {
89 0 : if (strcasecmp(key, "dsn") == 0 && dsn == NULL) {
90 0 : if (dsn)
91 : free(dsn);
92 0 : dsn = attr;
93 0 : } else if (strcasecmp(key, "uid") == 0 && uid == NULL) {
94 0 : if (uid)
95 : free(uid);
96 0 : uid = attr;
97 0 : } else if (strcasecmp(key, "pwd") == 0 && pwd == NULL) {
98 0 : if (pwd)
99 : free(pwd);
100 0 : pwd = attr;
101 0 : } else if (strcasecmp(key, "host") == 0 && host == NULL) {
102 0 : if (host)
103 : free(host);
104 0 : host = attr;
105 0 : } else if (strcasecmp(key, "port") == 0 && port == 0) {
106 0 : port = atoi(attr);
107 0 : free(attr);
108 0 : } else if (strcasecmp(key, "database") == 0 && dbname == NULL) {
109 0 : if (dbname)
110 : free(dbname);
111 0 : dbname = attr;
112 0 : } else if (strcasecmp(key, "mapToLongVarchar") == 0 && mapToLongVarchar == 0) {
113 0 : mapToLongVarchar = atoi(attr);
114 0 : free(attr);
115 : #ifdef ODBCDEBUG
116 0 : } else if (strcasecmp(key, "logfile") == 0 &&
117 : #ifdef NATIVE_WIN32
118 : _wgetenv(L"ODBCDEBUG")
119 : #else
120 0 : getenv("ODBCDEBUG")
121 : #endif
122 : == NULL) {
123 : /* environment trumps everything */
124 0 : if (ODBCdebug)
125 0 : free((void *) ODBCdebug); /* discard const */
126 : #ifdef NATIVE_WIN32
127 : size_t attrlen = strlen(attr);
128 : SQLWCHAR *wattr = malloc((attrlen + 1) * sizeof(SQLWCHAR));
129 : if (ODBCutf82wchar(attr,
130 : (SQLINTEGER) attrlen,
131 : wattr,
132 : (SQLLEN) ((attrlen + 1) * sizeof(SQLWCHAR)),
133 : NULL,
134 : NULL)) {
135 : free(wattr);
136 : wattr = NULL;
137 : }
138 : ODBCdebug = wattr;
139 : free(attr);
140 : #else
141 0 : ODBCdebug = attr;
142 : #endif
143 0 : allocated = true;
144 : #endif
145 : } else
146 0 : free(attr);
147 0 : free(key);
148 : }
149 0 : if (n < 0)
150 0 : goto nomem;
151 :
152 0 : if (dsn) {
153 0 : if (uid == NULL) {
154 0 : n = SQLGetPrivateProfileString(dsn, "uid", "", buf, sizeof(buf), "odbc.ini");
155 0 : if (n > 0 && buf[0]) {
156 0 : uid = strdup(buf);
157 0 : if (uid == NULL)
158 0 : goto nomem;
159 : }
160 : }
161 0 : if (pwd == NULL) {
162 0 : n = SQLGetPrivateProfileString(dsn, "pwd", "", buf, sizeof(buf), "odbc.ini");
163 0 : if (n > 0 && buf[0]) {
164 0 : pwd = strdup(buf);
165 0 : if (pwd == NULL)
166 0 : goto nomem;
167 : }
168 : }
169 0 : if (host == NULL) {
170 0 : n = SQLGetPrivateProfileString(dsn, "host", "", buf, sizeof(buf), "odbc.ini");
171 0 : if (n > 0 && buf[0]) {
172 0 : host = strdup(buf);
173 0 : if (host == NULL)
174 0 : goto nomem;
175 : }
176 : }
177 0 : if (port == 0) {
178 0 : n = SQLGetPrivateProfileString(dsn, "port", "", buf, sizeof(buf), "odbc.ini");
179 0 : if (n > 0 && buf[0]) {
180 0 : port = atoi(buf);
181 : }
182 : }
183 0 : if (dbname == NULL) {
184 0 : n = SQLGetPrivateProfileString(dsn, "database", "", buf, sizeof(buf), "odbc.ini");
185 0 : if (n > 0 && buf[0]) {
186 0 : dbname = strdup(buf);
187 0 : if (dbname == NULL)
188 0 : goto nomem;
189 : }
190 : }
191 : #ifdef ODBCDEBUG
192 0 : if (!allocated &&
193 : #ifdef NATIVE_WIN32
194 : _wgetenv(L"ODBCDEBUG")
195 : #else
196 0 : getenv("ODBCDEBUG")
197 : #endif
198 : == NULL) {
199 : /* if not set from InConnectionString argument
200 : * or environment, look in profile */
201 0 : n = SQLGetPrivateProfileString(dsn, "logfile", "", buf, sizeof(buf), "odbc.ini");
202 0 : if (n > 0 && buf[0]) {
203 0 : if (ODBCdebug)
204 0 : free((void *) ODBCdebug); /* discard const */
205 : #ifdef NATIVE_WIN32
206 : size_t attrlen = strlen(buf);
207 : SQLWCHAR *wattr = malloc((attrlen + 1) * sizeof(SQLWCHAR));
208 : if (ODBCutf82wchar(buf,
209 : (SQLINTEGER) attrlen,
210 : wattr,
211 : (SQLLEN) ((attrlen + 1) * sizeof(SQLWCHAR)),
212 : NULL,
213 : NULL)) {
214 : free(wattr);
215 : wattr = NULL;
216 : }
217 : ODBCdebug = wattr;
218 : #else
219 0 : ODBCdebug = strdup(buf);
220 : #endif
221 : }
222 : }
223 : #endif
224 : }
225 :
226 0 : if (uid != NULL && pwd != NULL) {
227 0 : rc = MNDBConnect(dbc, (SQLCHAR *) dsn, SQL_NTS,
228 : (SQLCHAR *) uid, SQL_NTS,
229 : (SQLCHAR *) pwd, SQL_NTS,
230 : host, port, dbname,
231 : mapToLongVarchar);
232 0 : if (SQL_SUCCEEDED(rc)) {
233 0 : rc = ODBCConnectionString(rc, dbc, OutConnectionString,
234 : BufferLength,
235 : StringLength2Ptr,
236 : dsn, uid, pwd, host, port,
237 : dbname, mapToLongVarchar);
238 : }
239 : } else {
240 0 : len = (SQLSMALLINT) strconcat_len(
241 : (char *) OutConnectionString, BufferLength,
242 : uid ? "" : "UID:Login ID=?;",
243 : pwd ? "" : "PWD:Password=?;",
244 : host ? "" : "*HOST:Server=?;",
245 : port ? "" : "*PORT:Port=?;",
246 : dbname ? "" : "*DATABASE:Database=?;",
247 : #ifdef ODBCDEBUG
248 0 : ODBCdebug ? "" : "*LOGFILE:Logfile=?;",
249 : #endif
250 : NULL);
251 :
252 0 : if (StringLength2Ptr)
253 0 : *StringLength2Ptr = len;
254 :
255 : rc = SQL_NEED_DATA;
256 : }
257 :
258 0 : bailout:
259 0 : if (dsn)
260 0 : free(dsn);
261 0 : if (uid)
262 0 : free(uid);
263 0 : if (pwd)
264 0 : free(pwd);
265 0 : if (host)
266 0 : free(host);
267 0 : if (dbname)
268 0 : free(dbname);
269 : return rc;
270 :
271 0 : nomem:
272 : /* Memory allocation error */
273 0 : addDbcError(dbc, "HY001", NULL, 0);
274 0 : rc = SQL_ERROR;
275 0 : goto bailout;
276 : }
277 :
278 : SQLRETURN SQL_API
279 : SQLBrowseConnect(SQLHDBC ConnectionHandle,
280 : SQLCHAR *InConnectionString,
281 : SQLSMALLINT StringLength1,
282 : SQLCHAR *OutConnectionString,
283 : SQLSMALLINT BufferLength,
284 : SQLSMALLINT *StringLength2Ptr)
285 : {
286 0 : ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
287 :
288 : #ifdef ODBCDEBUG
289 0 : ODBCLOG("SQLBrowseConnect %p", ConnectionHandle);
290 : #endif
291 :
292 0 : if (!isValidDbc(dbc))
293 : return SQL_INVALID_HANDLE;
294 :
295 0 : clearDbcErrors(dbc);
296 :
297 0 : return MNDBBrowseConnect(dbc, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr);
298 : }
299 :
300 : SQLRETURN SQL_API
301 : SQLBrowseConnectA(SQLHDBC ConnectionHandle,
302 : SQLCHAR *InConnectionString,
303 : SQLSMALLINT StringLength1,
304 : SQLCHAR *OutConnectionString,
305 : SQLSMALLINT BufferLength,
306 : SQLSMALLINT *StringLength2Ptr)
307 : {
308 0 : return SQLBrowseConnect(ConnectionHandle, InConnectionString, StringLength1, OutConnectionString, BufferLength, StringLength2Ptr);
309 : }
310 :
311 : SQLRETURN SQL_API
312 : SQLBrowseConnectW(SQLHDBC ConnectionHandle,
313 : SQLWCHAR *InConnectionString,
314 : SQLSMALLINT StringLength1,
315 : SQLWCHAR *OutConnectionString,
316 : SQLSMALLINT BufferLength,
317 : SQLSMALLINT *StringLength2Ptr)
318 : {
319 0 : ODBCDbc *dbc = (ODBCDbc *) ConnectionHandle;
320 0 : SQLCHAR *in = NULL, *out;
321 0 : SQLSMALLINT n;
322 0 : SQLRETURN rc;
323 :
324 : #ifdef ODBCDEBUG
325 0 : ODBCLOG("SQLBrowseConnectW %p", ConnectionHandle);
326 : #endif
327 :
328 0 : if (!isValidDbc(dbc))
329 : return SQL_INVALID_HANDLE;
330 :
331 0 : clearDbcErrors(dbc);
332 :
333 0 : fixWcharIn(InConnectionString, StringLength1, SQLCHAR, in,
334 : addDbcError, dbc, return SQL_ERROR);
335 0 : out = malloc(2048);
336 0 : if (out == NULL) {
337 : /* Memory allocation error */
338 0 : addDbcError(dbc, "HY001", NULL, 0);
339 0 : return SQL_ERROR;
340 : }
341 0 : rc = MNDBBrowseConnect(dbc, in, SQL_NTS, out, 2048, &n);
342 0 : if (SQL_SUCCEEDED(rc) || rc == SQL_NEED_DATA) {
343 0 : fixWcharOut(rc, out, n, OutConnectionString, BufferLength,
344 : StringLength2Ptr, 1, addDbcError, dbc);
345 : }
346 0 : free(out);
347 0 : if (in)
348 0 : free(in);
349 : return rc;
350 : }
|