⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 drvconn.c

📁 postgresql-odbc,跨平台应用
💻 C
字号:
/*-------  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 <winsock2.h>#endif#include <string.h>#ifdef WIN32#include <windowsx.h>#include "resource.h"#endif#include "pgapifunc.h"#include "dlg_specific.h"#define	NULL_IF_NULL(a) (a ? a : "(NULL)")static char * hide_password(const char *str){	char *outstr, *pwdp;	if (!str)	return NULL;	outstr = strdup(str);	if (pwdp = strstr(outstr, "PWD="), !pwdp)		pwdp = strstr(outstr, "pwd=");	if (pwdp)	{		char	*p;		for (p=pwdp + 4; *p && *p != ';'; p++)			*p = 'x';	}	return outstr;}/* prototypes */void		dconn_get_connect_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci);static void dconn_get_common_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci);#ifdef WIN32LRESULT CALLBACK 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. */#endifRETCODE		SQL_APIPGAPI_DriverConnect(					HDBC hdbc,					HWND hwnd,					const SQLCHAR FAR * szConnStrIn,					SQLSMALLINT cbConnStrIn,					SQLCHAR FAR * szConnStrOut,					SQLSMALLINT cbConnStrOutMax,					SQLSMALLINT FAR * pcbConnStrOut,					SQLUSMALLINT fDriverCompletion){	CSTR func = "PGAPI_DriverConnect";	ConnectionClass *conn = (ConnectionClass *) hdbc;	ConnInfo   *ci;#ifdef WIN32	RETCODE		dialog_result;#endif	BOOL		paramRequired, didUI = FALSE;	RETCODE		result;	char		*connStrIn = NULL;	char		connStrOut[MAX_CONNECT_STRING];	int			retval;	char		salt[5];	char		password_required = AUTH_REQ_OK;	ssize_t		len = 0;	SQLSMALLINT	lenStrout;	mylog("%s: entering...\n", func);	if (!conn)	{		CC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	connStrIn = make_string(szConnStrIn, cbConnStrIn, NULL, 0);#ifdef	FORCE_PASSWORD_DISPLAY	mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, connStrIn);	qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, connStrIn, fDriverCompletion);#else	if (get_qlog() || get_mylog())	{		char	*hide_str = hide_password(connStrIn);		mylog("**** PGAPI_DriverConnect: fDriverCompletion=%d, connStrIn='%s'\n", fDriverCompletion, NULL_IF_NULL(hide_str));		qlog("conn=%p, PGAPI_DriverConnect( in)='%s', fDriverCompletion=%d\n", conn, NULL_IF_NULL(hide_str), fDriverCompletion);		if (hide_str)			free(hide_str);	}#endif	/* FORCE_PASSWORD_DISPLAY */	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);	if (connStrIn)	{		free(connStrIn);		connStrIn = NULL;	}	/* Fill in any default parameters if they are not there. */	getDSNdefaults(ci);	/* initialize pg_version */	CC_initialize_pg_version(conn);	memset(salt, 0, sizeof(salt));#ifdef WIN32dialog:#endif	ci->focus_password = password_required;inolog("DriverCompletion=%d\n", fDriverCompletion);	switch (fDriverCompletion)	{#ifdef WIN32		case SQL_DRIVER_PROMPT:			dialog_result = dconn_DoDialog(hwnd, ci);			didUI = TRUE;			if (dialog_result != SQL_SUCCESS)				return dialog_result;			break;		case SQL_DRIVER_COMPLETE_REQUIRED:			/* Fall through */		case SQL_DRIVER_COMPLETE:			paramRequired = password_required;			/* Password is not a required parameter. */			if (ci->database[0] == '\0')				paramRequired = TRUE;			else if (ci->port[0] == '\0')				paramRequired = TRUE;#ifdef	WIN32			else if (ci->server[0] == '\0')				paramRequired = TRUE;#endif /* WIN32 */			if (paramRequired)			{				dialog_result = dconn_DoDialog(hwnd, ci);				didUI = TRUE;				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)	 */	paramRequired = FALSE;	if (ci->database[0] == '\0')		paramRequired = TRUE;	else if (ci->port[0] == '\0')		paramRequired = TRUE;#ifdef	WIN32	else if (ci->server[0] == '\0')		paramRequired = TRUE;#endif /* WIN32 */	if (paramRequired)	{		if (didUI)			return SQL_NO_DATA_FOUND;		CC_set_error(conn, CONN_OPENDB_ERROR, "connction string lacks some options", func);		return SQL_ERROR;	}inolog("before CC_connect\n");	/* do the actual connect */	retval = CC_connect(conn, password_required, salt);	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 = -retval;			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);*/		strncpy(szConnStrOut, connStrOut, cbConnStrOutMax);		if (len >= cbConnStrOutMax)		{			int			clen;			for (clen = cbConnStrOutMax - 1; clen >= 0 && szConnStrOut[clen] != ';'; clen--)				szConnStrOut[clen] = '\0';			result = SQL_SUCCESS_WITH_INFO;			CC_set_error(conn, CONN_TRUNCATED, "The buffer was too small for the ConnStrOut.", func);		}	}	if (pcbConnStrOut)		*pcbConnStrOut = (SQLSMALLINT) len;#ifdef	FORCE_PASSWORD_DISPLAY	if (cbConnStrOutMax > 0)	{		mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(szConnStrOut), len, cbConnStrOutMax);		qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(szConnStrOut));	}#else	if (get_qlog() || get_mylog())	{		char	*hide_str = NULL;		if (cbConnStrOutMax > 0)			hide_str = hide_password(szConnStrOut);		mylog("szConnStrOut = '%s' len=%d,%d\n", NULL_IF_NULL(hide_str), len, cbConnStrOutMax);		qlog("conn=%p, PGAPI_DriverConnect(out)='%s'\n", conn, NULL_IF_NULL(hide_str));		if (hide_str)			free(hide_str);	}#endif /* FORCE_PASSWORD_DISPLAY */	if (connStrIn)		free(connStrIn);	mylog("PGAPI_DriverConnect: returning %d\n", result);	return result;}#ifdef WIN32RETCODEdconn_DoDialog(HWND hwnd, ConnInfo *ci){	LRESULT			dialog_result;	mylog("dconn_DoDialog: ci = %p\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;}LRESULT CALLBACKdconn_FDriverConnectProc(						 HWND hdlg,						 UINT wMsg,						 WPARAM wParam,						 LPARAM lParam){	ConnInfo   *ci;	char	strbuf[64];	switch (wMsg)	{		case WM_INITDIALOG:			ci = (ConnInfo *) lParam;			/* Change the caption for the setup dialog */			SetWindowText(hdlg, "PostgreSQL Connection");			LoadString(s_hModule, IDS_ADVANCE_CONNECTION, strbuf, sizeof(strbuf));			SetWindowText(GetDlgItem(hdlg, IDC_DATASOURCE), strbuf);			/* 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);			ShowWindow(GetDlgItem(hdlg, IDC_DRIVER), SW_HIDE);			ShowWindow(GetDlgItem(hdlg, IDC_TEST), SW_HIDE);			if ('\0' != ci->server[0])				EnableWindow(GetDlgItem(hdlg, IDC_SERVER), FALSE);			if ('\0' != ci->port[0])				EnableWindow(GetDlgItem(hdlg, IDC_PORT), FALSE);			SetWindowLongPtr(hdlg, DWLP_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 *) GetWindowLongPtr(hdlg, DWLP_USER);					GetDlgStuff(hdlg, ci);				case IDCANCEL:					EndDialog(hdlg, GET_WM_COMMAND_ID(wParam, lParam) == IDOK);					return TRUE;				case IDC_DATASOURCE:					ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);					DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),								   hdlg, ds_options1Proc, (LPARAM) ci);					break;				case IDC_DRIVER:					ci = (ConnInfo *) GetWindowLongPtr(hdlg, DWLP_USER);					DialogBoxParam(s_hModule, MAKEINTRESOURCE(DLG_OPTIONS_DRV),								   hdlg, driver_optionsProc, (LPARAM) ci);					break;			}	}	return FALSE;}#endif   /* WIN32 */typedef	void (*copyfunc)(ConnInfo *, const char *attribute, const char *value);static voiddconn_get_attributes(copyfunc func, const SQLCHAR FAR * connect_string, ConnInfo *ci){	char	   *our_connect_string;	const	char	   *pair,			   *attribute,			   *value;	char	*equals;	char	   *strtok_arg;#ifdef	HAVE_STRTOK_R	char	   *last;#endif /* HAVE_STRTOK_R */	our_connect_string = strdup(connect_string);	strtok_arg = our_connect_string;#ifdef	FORCE_PASSWORD_DISPLAY	mylog("our_connect_string = '%s'\n", our_connect_string);#else	if (get_mylog())	{		char	*hide_str = hide_password(our_connect_string);		mylog("our_connect_string = '%s'\n", hide_str);		free(hide_str);	}#endif /* FORCE_PASSWORD_DISPLAY */	while (1)	{#ifdef	HAVE_STRTOK_R		pair = strtok_r(strtok_arg, ";", &last);#else		pair = strtok(strtok_arg, ";");#endif /* HAVE_STRTOK_R */		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' */#ifndef	FORCE_PASSWORD_DISPLAY		if (stricmp(attribute, INI_PASSWORD) == 0 ||		    stricmp(attribute, "pwd") == 0)			mylog("attribute = '%s', value = 'xxxxx'\n", attribute);		else#endif /* FORCE_PASSWORD_DISPLAY */			mylog("attribute = '%s', value = '%s'\n", attribute, value);		if (!attribute || !value)			continue;		/* Copy the appropriate value to the conninfo  */		(*func)(ci, attribute, value);	}	free(our_connect_string);}voiddconn_get_connect_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci){	CC_conninfo_init(ci);	dconn_get_attributes(copyAttributes, connect_string, ci);}static voiddconn_get_common_attributes(const SQLCHAR FAR * connect_string, ConnInfo *ci){	dconn_get_attributes(copyCommonAttributes, connect_string, ci);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -