4 * Description: This module contains only routines related to
5 * implementing SQLDriverConnect.
9 * API functions: SQLDriverConnect
11 * Comments: See "notice.txt" for copyright and license information.
20 #include "connection.h"
23 #include <sys/types.h>
24 #include <sys/socket.h>
34 #define stricmp(s1,s2) strcasecmp(s1,s2)
35 #define strnicmp(s1,s2,n) strncasecmp(s1,s2,n)
42 #include "pgapifunc.h"
51 #include "dlg_specific.h"
54 void dconn_get_connect_attributes(const UCHAR FAR *connect_string, ConnInfo *ci);
55 static void dconn_get_common_attributes(const UCHAR FAR *connect_string, ConnInfo *ci);
58 BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam);
59 RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci);
61 extern HINSTANCE NEAR s_hModule;/* Saved module handle. */
70 UCHAR FAR *szConnStrIn,
72 UCHAR FAR *szConnStrOut,
73 SWORD cbConnStrOutMax,
74 SWORD FAR *pcbConnStrOut,
75 UWORD fDriverCompletion)
77 static char *func = "PGAPI_DriverConnect";
78 ConnectionClass *conn = (ConnectionClass *) hdbc;
82 RETCODE dialog_result;
86 char connStrIn[MAX_CONNECT_STRING];
87 char connStrOut[MAX_CONNECT_STRING];
89 char password_required = FALSE;
94 mylog("%s: entering...\n", func);
98 CC_log_error(func, "", NULL);
99 return SQL_INVALID_HANDLE;
102 make_string(szConnStrIn, cbConnStrIn, connStrIn);
104 mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);
105 qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);
107 ci = &(conn->connInfo);
109 /* Parse the connect string and fill in conninfo for this hdbc. */
110 dconn_get_connect_attributes(connStrIn, ci);
113 * If the ConnInfo in the hdbc is missing anything, this function will
114 * fill them in from the registry (assuming of course there is a DSN
115 * given -- if not, it does nothing!)
117 getDSNinfo(ci, CONN_DONT_OVERWRITE);
118 dconn_get_common_attributes(connStrIn, ci);
119 logs_on_off(1, ci->drivers.debug, ci->drivers.commlog);
121 /* Fill in any default parameters if they are not there. */
123 /* initialize pg_version */
124 CC_initialize_pg_version(conn);
129 ci->focus_password = password_required;
131 switch (fDriverCompletion)
134 case SQL_DRIVER_PROMPT:
135 dialog_result = dconn_DoDialog(hwnd, ci);
136 if (dialog_result != SQL_SUCCESS)
137 return dialog_result;
140 case SQL_DRIVER_COMPLETE_REQUIRED:
144 case SQL_DRIVER_COMPLETE:
146 /* Password is not a required parameter. */
147 if (ci->username[0] == '\0' ||
148 ci->server[0] == '\0' ||
149 ci->database[0] == '\0' ||
150 ci->port[0] == '\0' ||
153 dialog_result = dconn_DoDialog(hwnd, ci);
154 if (dialog_result != SQL_SUCCESS)
155 return dialog_result;
159 case SQL_DRIVER_PROMPT:
160 case SQL_DRIVER_COMPLETE:
161 case SQL_DRIVER_COMPLETE_REQUIRED:
163 case SQL_DRIVER_NOPROMPT:
168 * Password is not a required parameter unless authentication asks for
169 * it. For now, I think it's better to just let the application ask
170 * over and over until a password is entered (the user can always hit
173 if (ci->username[0] == '\0' ||
174 ci->server[0] == '\0' ||
175 ci->database[0] == '\0' ||
178 /* (password_required && ci->password[0] == '\0')) */
180 return SQL_NO_DATA_FOUND;
183 /* do the actual connect */
184 retval = CC_connect(conn, password_required);
186 { /* need a password */
187 if (fDriverCompletion == SQL_DRIVER_NOPROMPT)
189 CC_log_error(func, "Need password but Driver_NoPrompt", conn);
190 return SQL_ERROR; /* need a password but not allowed to
196 password_required = TRUE;
199 return SQL_ERROR; /* until a better solution is found. */
203 else if (retval == 0)
205 /* error msg filled in above */
206 CC_log_error(func, "Error from CC_Connect", conn);
211 * Create the Output Connection String
213 result = SQL_SUCCESS;
215 lenStrout = cbConnStrOutMax;
216 if (conn->ms_jet && lenStrout > 255)
218 makeConnectString(connStrOut, ci, lenStrout);
219 len = strlen(connStrOut);
225 * Return the completed string to the caller. The correct method
226 * is to only construct the connect string if a dialog was put up,
227 * otherwise, it should just copy the connection input string to
228 * the output. However, it seems ok to just always construct an
229 * output string. There are possible bad side effects on working
230 * applications (Access) by implementing the correct behavior,
233 strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax);
235 if (len >= cbConnStrOutMax)
238 for (clen = strlen(szConnStrOut) - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)
239 szConnStrOut[clen] = '\0';
240 result = SQL_SUCCESS_WITH_INFO;
241 conn->errornumber = CONN_TRUNCATED;
242 conn->errormsg = "The buffer was too small for the ConnStrOut.";
247 *pcbConnStrOut = len;
249 mylog("szConnStrOut = '%s' len=%d,%d\n", szConnStrOut, len, cbConnStrOutMax);
250 qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut);
253 mylog("PGAPI_DRiverConnect: returning %d\n", result);
260 dconn_DoDialog(HWND hwnd, ConnInfo *ci)
264 mylog("dconn_DoDialog: ci = %u\n", ci);
268 dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG),
269 hwnd, dconn_FDriverConnectProc, (LPARAM) ci);
270 if (!dialog_result || (dialog_result == -1))
271 return SQL_NO_DATA_FOUND;
281 dconn_FDriverConnectProc(
292 ci = (ConnInfo *) lParam;
294 /* Change the caption for the setup dialog */
295 SetWindowText(hdlg, "PostgreSQL Connection");
297 SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection");
299 /* Hide the DSN and description fields */
300 ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE);
301 ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE);
302 ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE);
303 ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE);
305 SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for
307 SetDlgStuff(hdlg, ci);
309 if (ci->database[0] == '\0')
310 ; /* default focus */
311 else if (ci->server[0] == '\0')
312 SetFocus(GetDlgItem(hdlg, IDC_SERVER));
313 else if (ci->port[0] == '\0')
314 SetFocus(GetDlgItem(hdlg, IDC_PORT));
315 else if (ci->username[0] == '\0')
316 SetFocus(GetDlgItem(hdlg, IDC_USER));
317 else if (ci->focus_password)
318 SetFocus(GetDlgItem(hdlg, IDC_PASSWORD));
322 switch (GET_WM_COMMAND_ID(wParam, lParam))
325 ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
327 GetDlgStuff(hdlg, ci);
330 EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);
334 ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
335 DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),
336 hdlg, driver_optionsProc, (LPARAM) ci);
340 ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER);
341 DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS),
342 hdlg, ds_optionsProc, (LPARAM) ci);
354 dconn_get_connect_attributes(const UCHAR FAR *connect_string, ConnInfo *ci)
356 char *our_connect_string;
363 memset(ci, 0, sizeof(ConnInfo));
365 our_connect_string = strdup(connect_string);
366 strtok_arg = our_connect_string;
368 mylog("our_connect_string = '%s'\n", our_connect_string);
372 pair = strtok(strtok_arg, ";");
378 equals = strchr(pair, '=');
383 attribute = pair; /* ex. DSN */
384 value = equals + 1; /* ex. 'CEO co1' */
386 mylog("attribute = '%s', value = '%s'\n", attribute, value);
388 if (!attribute || !value)
391 /* Copy the appropriate value to the conninfo */
392 copyAttributes(ci, attribute, value);
396 free(our_connect_string);
400 dconn_get_common_attributes(const UCHAR FAR *connect_string, ConnInfo *ci)
402 char *our_connect_string;
409 our_connect_string = strdup(connect_string);
410 strtok_arg = our_connect_string;
412 mylog("our_connect_string = '%s'\n", our_connect_string);
416 pair = strtok(strtok_arg, ";");
422 equals = strchr(pair, '=');
427 attribute = pair; /* ex. DSN */
428 value = equals + 1; /* ex. 'CEO co1' */
430 mylog("attribute = '%s', value = '%s'\n", attribute, value);
432 if (!attribute || !value)
435 /* Copy the appropriate value to the conninfo */
436 copyCommonAttributes(ci, attribute, value);
440 free(our_connect_string);