4
* Description: This module contains only routines related to
5
* implementing SQLDriverConnect.
9
* API functions: SQLDriverConnect
11
* Comments: See "readme.txt" for copyright and license information.
20
#include "connection.h"
23
#include <sys/types.h>
24
#include <sys/socket.h>
36
#include "pgapifunc.h"
38
#include "dlg_specific.h"
40
#define FORCE_PASSWORD_DISPLAY
41
#define NULL_IF_NULL(a) (a ? a : "(NULL)")
43
static char * hide_password(const char *str)
47
if (!str) return NULL;
49
if (pwdp = strstr(outstr, "PWD="), !pwdp)
50
pwdp = strstr(outstr, "pwd=");
55
for (p=pwdp + 4; *p && *p != ';'; p++)
62
void dconn_get_connect_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci);
63
static void dconn_get_common_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci);
66
LRESULT CALLBACK dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
67
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
69
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
77
const SQLCHAR FAR * szConnStrIn,
78
SQLSMALLINT cbConnStrIn,
79
SQLCHAR FAR * szConnStrOut,
80
SQLSMALLINT cbConnStrOutMax,
81
SQLSMALLINT FAR * pcbConnStrOut,
82
SQLUSMALLINT fDriverCompletion)
84
CSTR func = "PGAPI_DriverConnect";
85
ConnectionClass *conn = (ConnectionClass *) hdbc;
89
RETCODE dialog_result;
91
BOOL paramRequired, didUI = FALSE;
93
char *connStrIn = NULL;
94
char connStrOut[MAX_CONNECT_STRING];
97
char password_required = AUTH_REQ_OK;
99
SQLSMALLINT lenStrout;
102
mylog("%s: entering...\n", func);
106
CC_log_error(func, "", NULL);
107
return SQL_INVALID_HANDLE;
110
connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0);
112
#ifdef FORCE_PASSWORD_DISPLAY
113
mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
114
qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
116
if (get_qlog() || get_mylog())
118
char *hide_str = hide_password(connStrIn);
120
mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str));
121
qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion);
125
#endif /* FORCE_PASSWORD_DISPLAY */
127
ci = &(conn->connInfo);
129
/* Parse the connect string and fill in conninfo for this hdbc. */
130
dconn_get_connect_attributes(connStrIn, ci);
133
* If the ConnInfo in the hdbc is missing anything, this function will
134
* fill them in from the registry (assuming of course there is a DSN
135
* given -- if not, it does nothing!)
137
getDSNinfo(ci, CONN_DONT_OVERWRITE);
138
dconn_get_common_attributes(connStrIn, ci);
139
logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
146
/* Fill in any default parameters if they are not there. */
148
/* initialize pg_version */
149
CC_initialize_pg_version(conn);
150
memset(salt, 0, sizeof(salt));
155
ci->focus_password = password_required;
157
inolog("DriverCompletion=%d\n", fDriverCompletion);
158
switch (fDriverCompletion)
161
case SQL_DRIVER_PROMPT:
162
dialog_result = dconn_DoDialog(hwnd, ci);
164
if (dialog_result != SQL_SUCCESS)
165
return dialog_result;
168
case SQL_DRIVER_COMPLETE_REQUIRED:
172
case SQL_DRIVER_COMPLETE:
174
paramRequired = password_required;
175
/* Password is not a required parameter. */
176
if (ci->database[0] == '\0')
177
paramRequired = TRUE;
178
else if (ci->port[0] == '\0')
179
paramRequired = TRUE;
181
else if (ci->server[0] == '\0')
182
paramRequired = TRUE;
186
dialog_result = dconn_DoDialog(hwnd, ci);
188
if (dialog_result != SQL_SUCCESS)
189
return dialog_result;
193
case SQL_DRIVER_PROMPT:
194
case SQL_DRIVER_COMPLETE:
195
case SQL_DRIVER_COMPLETE_REQUIRED:
197
case SQL_DRIVER_NOPROMPT:
202
* Password is not a required parameter unless authentication asks for
203
* it. For now, I think it's better to just let the application ask
204
* over and over until a password is entered (the user can always hit
207
paramRequired = FALSE;
208
if (ci->database[0] == '\0')
209
paramRequired = TRUE;
210
else if (ci->port[0] == '\0')
211
paramRequired = TRUE;
213
else if (ci->server[0] == '\0')
214
paramRequired = TRUE;
219
return SQL_NO_DATA_FOUND;
220
CC_set_error(conn, CONN_OPENDB_ERROR, "connction string lacks some options", func);
224
inolog("before CC_connect\n");
225
/* do the actual connect */
226
retval = CC_connect(conn, password_required, salt);
228
{ /* need a password */
229
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
231
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
232
return SQL_ERROR; /* need a password but not allowed to
238
password_required = -retval;
241
return SQL_ERROR; /* until a better solution is found. */
245
else if (retval == 0)
247
/* error msg filled in above */
248
CC_log_error(func, "Error from CC_Connect", conn);
253
* Create the Output Connection String
255
result = (1 == retval ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
257
lenStrout = cbConnStrOutMax;
258
if (conn->ms_jet && lenStrout > 255)
260
makeConnectString(connStrOut, ci, lenStrout);
261
len = strlen(connStrOut);
266
* Return the completed string to the caller. The correct method
267
* is to only construct the connect string if a dialog was put up,
268
* otherwise, it should just copy the connection input string to
269
* the output. However, it seems ok to just always construct an
270
* output string. There are possible bad side effects on working
271
* applications (Access) by implementing the correct behavior,
274
/*strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);*/
275
strncpy(szConnStrOut, connStrOut, cbConnStrOutMax);
277
if (len >= cbConnStrOutMax)
281
for (clen = cbConnStrOutMax - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)
282
szConnStrOut[clen] = '\0';
283
result = SQL_SUCCESS_WITH_INFO;
284
CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.", func);
289
*pcbConnStrOut = (SQLSMALLINT) len;
291
#ifdef FORCE_PASSWORD_DISPLAY
292
if (cbConnStrOutMax > 0)
294
mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(szConnStrOut), len, cbConnStrOutMax);
295
qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(szConnStrOut));
298
if (get_qlog() || get_mylog())
300
char *hide_str = NULL;
302
if (cbConnStrOutMax > 0)
303
hide_str = hide_password(szConnStrOut);
304
mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax);
305
qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str));
309
#endif /* FORCE_PASSWORD_DISPLAY */
313
mylog("PGAPI_DriverConnect: returning %d\n", result);
320
dconn_DoDialog(HWND hwnd, ConnInfo *ci)
322
LRESULT dialog_result;
324
mylog("dconn_DoDialog: ci = %p\n", ci);
328
dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
329
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
330
if (!dialog_result || (dialog_result == -1))
331
return SQL_NO_DATA_FOUND;
341
dconn_FDriverConnectProc(
353
ci = (ConnInfo *) lParam;
355
/* Change the caption for the setup dialog */
356
SetWindowText(hdlg, "PostgreSQL Connection");
358
LoadString(s_hModule, IDS_ADVANCE_CONNECTION, strbuf, sizeof(strbuf));
359
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), strbuf);
361
/* Hide the DSN and description fields */
362
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
363
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
364
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
365
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
366
ShowWindow(GetDlgItem(hdlg, IDC_DRIVER), SW_HIDE);
367
ShowWindow(GetDlgItem(hdlg, IDC_TEST), SW_HIDE);
368
if ('\0' != ci->server[0])
369
EnableWindow(GetDlgItem(hdlg, IDC_SERVER), FALSE);
370
if ('\0' != ci->port[0])
371
EnableWindow(GetDlgItem(hdlg, IDC_PORT), FALSE);
373
SetWindowLongPtr(hdlg, DWLP_USER, lParam); /* Save the ConnInfo for
375
SetDlgStuff(hdlg, ci);
377
if (ci->database[0] == '\0')
378
; /* default focus */
379
else if (ci->server[0] == '\0')
380
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
381
else if (ci->port[0] == '\0')
382
SetFocus(GetDlgItem(hdlg, IDC_PORT));
383
else if (ci->username[0] == '\0')
384
SetFocus(GetDlgItem(hdlg, IDC_USER));
385
else if (ci->focus_password)
386
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
390
switch (GET_WM_COMMAND_ID(wParam, lParam))
393
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
395
GetDlgStuff(hdlg, ci);
398
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
402
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
403
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
404
hdlg, ds_options1Proc, (LPARAM) ci);
408
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
409
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
410
hdlg, driver_optionsProc, (LPARAM) ci);
419
#define ATTRIBUTE_DELIMITER ';'
420
#define OPENING_BRACKET '{'
421
#define CLOSING_BRACKET '}'
423
typedef BOOL (*copyfunc)(ConnInfo *, const char *attribute, const char *value);
425
dconn_get_attributes(copyfunc func, const SQLCHAR FAR * connect_string, ConnInfo *ci)
427
char *our_connect_string;
437
#endif /* HAVE_STRTOK_R */
439
if (our_connect_string = strdup(connect_string), NULL == our_connect_string)
441
strtok_arg = our_connect_string;
443
#ifdef FORCE_PASSWORD_DISPLAY
444
mylog("our_connect_string = '%s'\n", our_connect_string);
448
char *hide_str = hide_password(our_connect_string);
450
mylog("our_connect_string = '%s'\n", hide_str);
453
#endif /* FORCE_PASSWORD_DISPLAY */
455
termp = strchr(our_connect_string, '\0');
460
pair = strtok_r(strtok_arg, ";", &last);
462
pair = strtok(strtok_arg, ";");
463
#endif /* HAVE_STRTOK_R */
469
equals = strchr(pair, '=');
474
attribute = pair; /* ex. DSN */
475
value = equals + 1; /* ex. 'CEO co1' *
477
* Values enclosed with braces({}) can contain ; etc
478
* We don't remove the braces here because
479
* decode_or_remove_braces() in dlg_specifi.c
480
* would remove them later.
481
* Just correct the misdetected delimter(;).
483
if (OPENING_BRACKET == *value)
485
delp = strchr(value, '\0');
486
if (NULL == delp) continue; /* shouldn't occur */
489
/* there's a corresponding closing bracket? */
490
if (CLOSING_BRACKET == delp[-1])
497
/* Where's a corresponding closing bracket? */
498
closep = strchr(value, CLOSING_BRACKET);
501
closep = strchr(delp + 1, CLOSING_BRACKET);
502
if (NULL != closep) /* the delimiter is misdetected */
504
*delp = ATTRIBUTE_DELIMITER;
505
strtok_arg = closep + 1;
506
if (delp = strchr(closep + 1, ATTRIBUTE_DELIMITER), NULL != delp)
509
strtok_arg = delp + 1;
511
if (strtok_arg + 1 >= termp)
518
#ifndef FORCE_PASSWORD_DISPLAY
519
if (stricmp(attribute, INI_PASSWORD) == 0 ||
520
stricmp(attribute, "pwd") == 0)
521
mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
523
#endif /* FORCE_PASSWORD_DISPLAY */
524
mylog("attribute = '%s', value = '%s'\n", attribute, value);
526
if (!attribute || !value)
529
/* Copy the appropriate value to the conninfo */
530
(*func)(ci, attribute, value);
534
free(our_connect_string);
538
dconn_get_connect_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci)
541
CC_conninfo_init(ci);
542
dconn_get_attributes(copyAttributes, connect_string, ci);
546
dconn_get_common_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci)
548
dconn_get_attributes(copyCommonAttributes, connect_string, ci);
4
* Description: This module contains only routines related to
5
* implementing SQLDriverConnect.
9
* API functions: SQLDriverConnect
11
* Comments: See "readme.txt" for copyright and license information.
20
#include "connection.h"
24
#include <sys/types.h>
25
#include <sys/socket.h>
37
#include "pgapifunc.h"
39
#include "dlg_specific.h"
41
#define FORCE_PASSWORD_DISPLAY
42
#define NULL_IF_NULL(a) (a ? a : "(NULL)")
44
#ifndef FORCE_PASSWORD_DISPLAY
45
static char * hide_password(const char *str)
49
if (!str) return NULL;
51
if (pwdp = strstr(outstr, "PWD="), !pwdp)
52
pwdp = strstr(outstr, "pwd=");
57
for (p=pwdp + 4; *p && *p != ';'; p++)
65
static void dconn_get_connect_attributes(const char *connect_string, ConnInfo *ci);
66
static void dconn_get_common_attributes(const char *connect_string, ConnInfo *ci);
69
LRESULT CALLBACK dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
70
RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
72
extern HINSTANCE NEAR s_hModule; /* Saved module handle. */
77
PGAPI_DriverConnect(HDBC hdbc,
79
const SQLCHAR FAR * szConnStrIn,
80
SQLSMALLINT cbConnStrIn,
81
SQLCHAR FAR * szConnStrOut,
82
SQLSMALLINT cbConnStrOutMax,
83
SQLSMALLINT FAR * pcbConnStrOut,
84
SQLUSMALLINT fDriverCompletion)
86
CSTR func = "PGAPI_DriverConnect";
87
ConnectionClass *conn = (ConnectionClass *) hdbc;
91
RETCODE dialog_result;
93
BOOL paramRequired, didUI = FALSE;
95
char *connStrIn = NULL;
96
char connStrOut[MAX_CONNECT_STRING];
99
char password_required = AUTH_REQ_OK;
101
SQLSMALLINT lenStrout;
104
mylog("%s: entering...\n", func);
108
CC_log_error(func, "", NULL);
109
return SQL_INVALID_HANDLE;
112
connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0);
114
#ifdef FORCE_PASSWORD_DISPLAY
115
mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
116
qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
118
if (get_qlog() || get_mylog())
120
char *hide_str = hide_password(connStrIn);
122
mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str));
123
qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion);
127
#endif /* FORCE_PASSWORD_DISPLAY */
129
ci = &(conn->connInfo);
131
/* Parse the connect string and fill in conninfo for this hdbc. */
132
dconn_get_connect_attributes(connStrIn, ci);
135
* If the ConnInfo in the hdbc is missing anything, this function will
136
* fill them in from the registry (assuming of course there is a DSN
137
* given -- if not, it does nothing!)
139
getDSNinfo(ci, CONN_DONT_OVERWRITE);
140
dconn_get_common_attributes(connStrIn, ci);
141
logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
148
/* Fill in any default parameters if they are not there. */
150
/* initialize pg_version */
151
CC_initialize_pg_version(conn);
152
memset(salt, 0, sizeof(salt));
157
ci->focus_password = password_required;
159
inolog("DriverCompletion=%d\n", fDriverCompletion);
160
switch (fDriverCompletion)
163
case SQL_DRIVER_PROMPT:
164
dialog_result = dconn_DoDialog(hwnd, ci);
166
if (dialog_result != SQL_SUCCESS)
167
return dialog_result;
170
case SQL_DRIVER_COMPLETE_REQUIRED:
174
case SQL_DRIVER_COMPLETE:
176
paramRequired = password_required;
177
/* Password is not a required parameter. */
178
if (ci->database[0] == '\0')
179
paramRequired = TRUE;
180
else if (ci->port[0] == '\0')
181
paramRequired = TRUE;
183
else if (ci->server[0] == '\0')
184
paramRequired = TRUE;
188
dialog_result = dconn_DoDialog(hwnd, ci);
190
if (dialog_result != SQL_SUCCESS)
191
return dialog_result;
195
case SQL_DRIVER_PROMPT:
196
case SQL_DRIVER_COMPLETE:
197
case SQL_DRIVER_COMPLETE_REQUIRED:
199
case SQL_DRIVER_NOPROMPT:
204
* Password is not a required parameter unless authentication asks for
205
* it. For now, I think it's better to just let the application ask
206
* over and over until a password is entered (the user can always hit
209
paramRequired = FALSE;
210
if (ci->database[0] == '\0')
211
paramRequired = TRUE;
212
else if (ci->port[0] == '\0')
213
paramRequired = TRUE;
215
else if (ci->server[0] == '\0')
216
paramRequired = TRUE;
221
return SQL_NO_DATA_FOUND;
222
CC_set_error(conn, CONN_OPENDB_ERROR, "connction string lacks some options", func);
226
inolog("before CC_connect\n");
227
/* do the actual connect */
228
retval = CC_connect(conn, password_required, salt);
230
{ /* need a password */
231
if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
233
CC_log_error(func, "Need password but Driver_NoPrompt", conn);
234
return SQL_ERROR; /* need a password but not allowed to
240
password_required = -retval;
243
return SQL_ERROR; /* until a better solution is found. */
247
else if (retval == 0)
249
/* error msg filled in above */
250
CC_log_error(func, "Error from CC_Connect", conn);
255
* Create the Output Connection String
257
result = (1 == retval ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO);
259
lenStrout = cbConnStrOutMax;
260
if (conn->ms_jet && lenStrout > 255)
262
makeConnectString(connStrOut, ci, lenStrout);
263
len = strlen(connStrOut);
268
* Return the completed string to the caller. The correct method
269
* is to only construct the connect string if a dialog was put up,
270
* otherwise, it should just copy the connection input string to
271
* the output. However, it seems ok to just always construct an
272
* output string. There are possible bad side effects on working
273
* applications (Access) by implementing the correct behavior,
276
/*strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);*/
277
strncpy((char *) szConnStrOut, connStrOut, cbConnStrOutMax);
279
if (len >= cbConnStrOutMax)
283
for (clen = cbConnStrOutMax - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)
284
szConnStrOut[clen] = '\0';
285
result = SQL_SUCCESS_WITH_INFO;
286
CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.", func);
291
*pcbConnStrOut = (SQLSMALLINT) len;
293
#ifdef FORCE_PASSWORD_DISPLAY
294
if (cbConnStrOutMax > 0)
296
mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL((char *) szConnStrOut), len, cbConnStrOutMax);
297
qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL((char *) szConnStrOut));
300
if (get_qlog() || get_mylog())
302
char *hide_str = NULL;
304
if (cbConnStrOutMax > 0)
305
hide_str = hide_password(szConnStrOut);
306
mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax);
307
qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str));
311
#endif /* FORCE_PASSWORD_DISPLAY */
315
mylog("PGAPI_DriverConnect: returning %d\n", result);
322
dconn_DoDialog(HWND hwnd, ConnInfo *ci)
324
LRESULT dialog_result;
326
mylog("dconn_DoDialog: ci = %p\n", ci);
330
dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
331
hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
332
if (!dialog_result || (dialog_result == -1))
333
return SQL_NO_DATA_FOUND;
343
dconn_FDriverConnectProc(
355
ci = (ConnInfo *) lParam;
357
/* Change the caption for the setup dialog */
358
SetWindowText(hdlg, "PostgreSQL Connection");
360
LoadString(s_hModule, IDS_ADVANCE_CONNECTION, strbuf, sizeof(strbuf));
361
SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), strbuf);
363
/* Hide the DSN and description fields */
364
ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
365
ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
366
ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
367
ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
368
ShowWindow(GetDlgItem(hdlg, IDC_DRIVER), SW_HIDE);
369
ShowWindow(GetDlgItem(hdlg, IDC_TEST), SW_HIDE);
370
if ('\0' != ci->server[0])
371
EnableWindow(GetDlgItem(hdlg, IDC_SERVER), FALSE);
372
if ('\0' != ci->port[0])
373
EnableWindow(GetDlgItem(hdlg, IDC_PORT), FALSE);
375
SetWindowLongPtr(hdlg, DWLP_USER, lParam); /* Save the ConnInfo for
377
SetDlgStuff(hdlg, ci);
379
if (ci->database[0] == '\0')
380
; /* default focus */
381
else if (ci->server[0] == '\0')
382
SetFocus(GetDlgItem(hdlg, IDC_SERVER));
383
else if (ci->port[0] == '\0')
384
SetFocus(GetDlgItem(hdlg, IDC_PORT));
385
else if (ci->username[0] == '\0')
386
SetFocus(GetDlgItem(hdlg, IDC_USER));
387
else if (ci->focus_password)
388
SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
392
switch (GET_WM_COMMAND_ID(wParam, lParam))
395
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
397
GetDlgStuff(hdlg, ci);
400
EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
404
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
405
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
406
hdlg, ds_options1Proc, (LPARAM) ci);
410
ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);
411
DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
412
hdlg, driver_optionsProc, (LPARAM) ci);
421
#define ATTRIBUTE_DELIMITER ';'
422
#define OPENING_BRACKET '{'
423
#define CLOSING_BRACKET '}'
425
typedef BOOL (*copyfunc)(ConnInfo *, const char *attribute, const char *value);
427
dconn_get_attributes(copyfunc func, const char *connect_string, ConnInfo *ci)
429
char *our_connect_string;
439
#endif /* HAVE_STRTOK_R */
441
if (our_connect_string = strdup(connect_string), NULL == our_connect_string)
443
strtok_arg = our_connect_string;
445
#ifdef FORCE_PASSWORD_DISPLAY
446
mylog("our_connect_string = '%s'\n", our_connect_string);
450
char *hide_str = hide_password(our_connect_string);
452
mylog("our_connect_string = '%s'\n", hide_str);
455
#endif /* FORCE_PASSWORD_DISPLAY */
457
termp = strchr(our_connect_string, '\0');
462
pair = strtok_r(strtok_arg, ";", &last);
464
pair = strtok(strtok_arg, ";");
465
#endif /* HAVE_STRTOK_R */
471
equals = strchr(pair, '=');
476
attribute = pair; /* ex. DSN */
477
value = equals + 1; /* ex. 'CEO co1' */
479
* Values enclosed with braces({}) can contain ; etc
480
* We don't remove the braces here because
481
* decode_or_remove_braces() in dlg_specifi.c
482
* would remove them later.
483
* Just correct the misdetected delimter(;).
485
if (OPENING_BRACKET == *value)
487
delp = strchr(value, '\0');
488
if (NULL == delp) continue; /* shouldn't occur */
491
/* there's a corresponding closing bracket? */
492
if (CLOSING_BRACKET == delp[-1])
499
/* Where's a corresponding closing bracket? */
500
closep = strchr(value, CLOSING_BRACKET);
503
closep = strchr(delp + 1, CLOSING_BRACKET);
504
if (NULL != closep) /* the delimiter is misdetected */
506
*delp = ATTRIBUTE_DELIMITER;
507
strtok_arg = closep + 1;
508
if (delp = strchr(closep + 1, ATTRIBUTE_DELIMITER), NULL != delp)
511
strtok_arg = delp + 1;
513
if (strtok_arg + 1 >= termp)
520
#ifndef FORCE_PASSWORD_DISPLAY
521
if (stricmp(attribute, INI_PASSWORD) == 0 ||
522
stricmp(attribute, "pwd") == 0)
523
mylog("attribute = '%s', value = 'xxxxx'\n", attribute);
525
#endif /* FORCE_PASSWORD_DISPLAY */
526
mylog("attribute = '%s', value = '%s'\n", attribute, value);
528
if (!attribute || !value)
531
/* Copy the appropriate value to the conninfo */
532
(*func)(ci, attribute, value);
536
free(our_connect_string);
540
dconn_get_connect_attributes(const char *connect_string, ConnInfo *ci)
543
CC_conninfo_init(ci, COPY_GLOBALS);
544
dconn_get_attributes(copyAttributes, connect_string, ci);
548
dconn_get_common_attributes(const char *connect_string, ConnInfo *ci)
550
dconn_get_attributes(copyCommonAttributes, connect_string, ci);