diff options
author | Hiroshi Inoue <inoue@tpf.co.jp> | 2002-01-11 02:50:01 +0000 |
---|---|---|
committer | Hiroshi Inoue <inoue@tpf.co.jp> | 2002-01-11 02:50:01 +0000 |
commit | f43b5de649cdf8a36f7d90a96932800cb0e34162 (patch) | |
tree | 6fb1ec57cff266680ab2adaf8c0976a643627b7c /src/interfaces/odbc/windev/drvconn.c | |
parent | 5370cd6b03610bdb6c6dee0fbf87ad9cdf524395 (diff) |
Add a directory to save the changes until 7.3-tree is branched.
Diffstat (limited to 'src/interfaces/odbc/windev/drvconn.c')
-rw-r--r-- | src/interfaces/odbc/windev/drvconn.c | 435 |
1 files changed, 435 insertions, 0 deletions
diff --git a/src/interfaces/odbc/windev/drvconn.c b/src/interfaces/odbc/windev/drvconn.c new file mode 100644 index 00000000000..e369525ca02 --- /dev/null +++ b/src/interfaces/odbc/windev/drvconn.c @@ -0,0 +1,435 @@ +/*------- + Module: drvconn.c + * + * Description: This module contains only routines related to + * implementing SQLDriverConnect. + * + * Classes: n/a + * + * API functions: SQLDriverConnect + * + * Comments: See "notice.txt" for copyright and license information. + *------- + */ + +#include "psqlodbc.h" + +#include <stdio.h> +#include <stdlib.h> + +#include "connection.h" + +#ifndef WIN32 +#include <sys/types.h> +#include <sys/socket.h> +#define NEAR +#else +#include <winsock.h> +#endif + +#include <string.h> + +#ifdef WIN32 +#include <windowsx.h> +#include "resource.h" +#endif +#include "pgapifunc.h" + +#ifndef TRUE +#define TRUE (BOOL)1 +#endif +#ifndef FALSE +#define FALSE (BOOL)0 +#endif + +#include "dlg_specific.h" + +/* prototypes */ +void dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci); +static void dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci); + +#ifdef WIN32 +BOOL FAR PASCAL dconn_FDriverConnectProc(HWND hdlg, UINT wMsg, WPARAM wParam, LPARAM lParam); +RETCODE dconn_DoDialog(HWND hwnd, ConnInfo *ci); + +extern HINSTANCE NEAR s_hModule; /* Saved module handle. */ +#endif + + +RETCODE SQL_API +PGAPI_DriverConnect( + HDBC hdbc, + HWND hwnd, + UCHAR FAR * szConnStrIn, + SWORD cbConnStrIn, + UCHAR FAR * szConnStrOut, + SWORD cbConnStrOutMax, + SWORD FAR * pcbConnStrOut, + UWORD fDriverCompletion) +{ + static char *func = "PGAPI_DriverConnect"; + ConnectionClass *conn = (ConnectionClass *) hdbc; + ConnInfo *ci; + +#ifdef WIN32 + RETCODE dialog_result; +#endif + RETCODE result; + char connStrIn[MAX_CONNECT_STRING]; + char connStrOut[MAX_CONNECT_STRING]; + int retval; + char password_required = FALSE; + int len = 0; + SWORD lenStrout; + + + mylog("%s: entering...\n", func); + + if (!conn) + { + CC_log_error(func, "", NULL); + return SQL_INVALID_HANDLE; + } + + make_string(szConnStrIn, cbConnStrIn, connStrIn); + + mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn); + qlog("conn=%u, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion); + + ci = &(conn->connInfo); + + /* Parse the connect string and fill in conninfo for this hdbc. */ + dconn_get_connect_attributes(connStrIn, ci); + + /* + * If the ConnInfo in the hdbc is missing anything, this function will + * fill them in from the registry (assuming of course there is a DSN + * given -- if not, it does nothing!) + */ + getDSNinfo(ci, CONN_DONT_OVERWRITE); + dconn_get_common_attributes(connStrIn, ci); + logs_on_off(1, ci->drivers.debug, ci->drivers.commlog); + + /* Fill in any default parameters if they are not there. */ + getDSNdefaults(ci); + /* initialize pg_version */ + CC_initialize_pg_version(conn); + +#ifdef WIN32 +dialog: +#endif + ci->focus_password = password_required; + + switch (fDriverCompletion) + { +#ifdef WIN32 + case SQL_DRIVER_PROMPT: + dialog_result = dconn_DoDialog(hwnd, ci); + if (dialog_result != SQL_SUCCESS) + return dialog_result; + break; + + case SQL_DRIVER_COMPLETE_REQUIRED: + + /* Fall through */ + + case SQL_DRIVER_COMPLETE: + + /* Password is not a required parameter. */ + if (ci->username[0] == '\0' || + ci->server[0] == '\0' || + ci->database[0] == '\0' || + ci->port[0] == '\0' || + password_required) + { + dialog_result = dconn_DoDialog(hwnd, ci); + if (dialog_result != SQL_SUCCESS) + return dialog_result; + } + break; +#else + case SQL_DRIVER_PROMPT: + case SQL_DRIVER_COMPLETE: + case SQL_DRIVER_COMPLETE_REQUIRED: +#endif + case SQL_DRIVER_NOPROMPT: + break; + } + + /* + * Password is not a required parameter unless authentication asks for + * it. For now, I think it's better to just let the application ask + * over and over until a password is entered (the user can always hit + * Cancel to get out) + */ + if (ci->username[0] == '\0' || + ci->server[0] == '\0' || + ci->database[0] == '\0' || + ci->port[0] == '\0') + { + /* (password_required && ci->password[0] == '\0')) */ + + return SQL_NO_DATA_FOUND; + } + + /* do the actual connect */ + retval = CC_connect(conn, password_required); + if (retval < 0) + { /* need a password */ + if (fDriverCompletion == SQL_DRIVER_NOPROMPT) + { + CC_log_error(func, "Need password but Driver_NoPrompt", conn); + return SQL_ERROR; /* need a password but not allowed to + * prompt so error */ + } + else + { +#ifdef WIN32 + password_required = TRUE; + goto dialog; +#else + return SQL_ERROR; /* until a better solution is found. */ +#endif + } + } + else if (retval == 0) + { + /* error msg filled in above */ + CC_log_error(func, "Error from CC_Connect", conn); + return SQL_ERROR; + } + + /* + * Create the Output Connection String + */ + result = SQL_SUCCESS; + + lenStrout = cbConnStrOutMax; + if (conn->ms_jet && lenStrout > 255) + lenStrout = 255; + makeConnectString(connStrOut, ci, lenStrout); + len = strlen(connStrOut); + + if (szConnStrOut) + { + /* + * Return the completed string to the caller. The correct method + * is to only construct the connect string if a dialog was put up, + * otherwise, it should just copy the connection input string to + * the output. However, it seems ok to just always construct an + * output string. There are possible bad side effects on working + * applications (Access) by implementing the correct behavior, + * anyway. + */ + strncpy_null(szConnStrOut, connStrOut, cbConnStrOutMax); + + if (len >= cbConnStrOutMax) + { + int clen; + + for (clen = strlen(szConnStrOut) - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--) + szConnStrOut[clen] = '\0'; + result = SQL_SUCCESS_WITH_INFO; + conn->errornumber = CONN_TRUNCATED; + conn->errormsg = "The buffer was too small for the ConnStrOut."; + } + } + + if (pcbConnStrOut) + *pcbConnStrOut = len; + + mylog("szConnStrOut = '%s' len=%d,%d\n", szConnStrOut, len, cbConnStrOutMax); + qlog("conn=%u, PGAPI_DriverConnect(out)='%s'\n", conn, szConnStrOut); + + + mylog("PGAPI_DRiverConnect: returning %d\n", result); + return result; +} + + +#ifdef WIN32 +RETCODE +dconn_DoDialog(HWND hwnd, ConnInfo *ci) +{ + int dialog_result; + + mylog("dconn_DoDialog: ci = %u\n", ci); + + if (hwnd) + { + dialog_result = DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_CONFIG), + hwnd, dconn_FDriverConnectProc, (LPARAM) ci); + if (!dialog_result || (dialog_result == -1)) + return SQL_NO_DATA_FOUND; + else + return SQL_SUCCESS; + } + + return SQL_ERROR; +} + + +BOOL FAR PASCAL +dconn_FDriverConnectProc( + HWND hdlg, + UINT wMsg, + WPARAM wParam, + LPARAM lParam) +{ + ConnInfo *ci; + + switch (wMsg) + { + case WM_INITDIALOG: + ci = (ConnInfo *) lParam; + + /* Change the caption for the setup dialog */ + SetWindowText(hdlg, "PostgreSQL Connection"); + + SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), "Connection"); + + /* Hide the DSN and description fields */ + ShowWindow(GetDlgItem(hdlg, IDC_DSNAMETEXT), SW_HIDE); + ShowWindow(GetDlgItem(hdlg, IDC_DSNAME), SW_HIDE); + ShowWindow(GetDlgItem(hdlg, IDC_DESCTEXT), SW_HIDE); + ShowWindow(GetDlgItem(hdlg, IDC_DESC), SW_HIDE); + + SetWindowLong(hdlg, DWL_USER, lParam); /* Save the ConnInfo for + * the "OK" */ + SetDlgStuff(hdlg, ci); + + if (ci->database[0] == '\0') + ; /* default focus */ + else if (ci->server[0] == '\0') + SetFocus(GetDlgItem(hdlg, IDC_SERVER)); + else if (ci->port[0] == '\0') + SetFocus(GetDlgItem(hdlg, IDC_PORT)); + else if (ci->username[0] == '\0') + SetFocus(GetDlgItem(hdlg, IDC_USER)); + else if (ci->focus_password) + SetFocus(GetDlgItem(hdlg, IDC_PASSWORD)); + break; + + case WM_COMMAND: + switch (GET_WM_COMMAND_ID(wParam, lParam)) + { + case IDOK: + ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); + + GetDlgStuff(hdlg, ci); + + case IDCANCEL: + EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK); + return TRUE; + + case IDC_DRIVER: + ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); + DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV), + hdlg, driver_optionsProc, (LPARAM) ci); + break; + + case IDC_DATASOURCE: + ci = (ConnInfo *) GetWindowLong(hdlg, DWL_USER); + DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DS), + hdlg, ds_optionsProc, (LPARAM) ci); + break; + } + } + + return FALSE; +} +#endif /* WIN32 */ + + +void +dconn_get_connect_attributes(const UCHAR FAR * connect_string, ConnInfo *ci) +{ + char *our_connect_string; + char *pair, + *attribute, + *value, + *equals; + char *strtok_arg; + + memset(ci, 0, sizeof(ConnInfo)); +#ifdef DRIVER_CURSOR_IMPLEMENT + ci->updatable_cursors = 1; +#endif /* DRIVER_CURSOR_IMPLEMENT */ + + our_connect_string = strdup(connect_string); + strtok_arg = our_connect_string; + + mylog("our_connect_string = '%s'\n", our_connect_string); + + while (1) + { + pair = strtok(strtok_arg, ";"); + if (strtok_arg) + strtok_arg = 0; + if (!pair) + break; + + equals = strchr(pair, '='); + if (!equals) + continue; + + *equals = '\0'; + attribute = pair; /* ex. DSN */ + value = equals + 1; /* ex. 'CEO co1' */ + + mylog("attribute = '%s', value = '%s'\n", attribute, value); + + if (!attribute || !value) + continue; + + /* Copy the appropriate value to the conninfo */ + copyAttributes(ci, attribute, value); + + } + + free(our_connect_string); +} + +static void +dconn_get_common_attributes(const UCHAR FAR * connect_string, ConnInfo *ci) +{ + char *our_connect_string; + char *pair, + *attribute, + *value, + *equals; + char *strtok_arg; + + our_connect_string = strdup(connect_string); + strtok_arg = our_connect_string; + + mylog("our_connect_string = '%s'\n", our_connect_string); + + while (1) + { + pair = strtok(strtok_arg, ";"); + if (strtok_arg) + strtok_arg = 0; + if (!pair) + break; + + equals = strchr(pair, '='); + if (!equals) + continue; + + *equals = '\0'; + attribute = pair; /* ex. DSN */ + value = equals + 1; /* ex. 'CEO co1' */ + + mylog("attribute = '%s', value = '%s'\n", attribute, value); + + if (!attribute || !value) + continue; + + /* Copy the appropriate value to the conninfo */ + copyCommonAttributes(ci, attribute, value); + + } + + free(our_connect_string); +} |