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

📄 fe-connect.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
/*------------------------------------------------------------------------- * * fe-connect.c *	  functions related to setting up a connection to the backend * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.98 1999/06/17 15:16:04 momjian Exp $ * *------------------------------------------------------------------------- */#include "libpq-fe.h"#include "libpq-int.h"#include "fe-auth.h"#include "postgres.h"#include <stdlib.h>#ifdef WIN32#include "win32.h"#else#if !defined(NO_UNISTD_H)#include <unistd.h>#endif#include <netdb.h>#include <netinet/tcp.h>#endif#include <fcntl.h>#include <string.h>#include <errno.h>#include <ctype.h>				/* for isspace() */#ifndef HAVE_STRDUP#include "strdup.h"#endif#ifdef HAVE_CRYPT_H#include <crypt.h>#endif#ifdef MULTIBYTE#include "mb/pg_wchar.h"#endifstatic ConnStatusType connectDB(PGconn *conn);static PGconn *makeEmptyPGconn(void);static void freePGconn(PGconn *conn);static void closePGconn(PGconn *conn);static int	conninfo_parse(const char *conninfo, char *errorMessage);static char *conninfo_getval(char *keyword);static void conninfo_free(void);static void defaultNoticeProcessor(void *arg, const char *message);/* XXX Why is this not static? */void		PQsetenv(PGconn *conn);#define NOTIFYLIST_INITIAL_SIZE 10#define NOTIFYLIST_GROWBY 10/* ---------- * Definition of the conninfo parameters and their fallback resources. * If Environment-Var and Compiled-in are specified as NULL, no * fallback is available. If after all no value can be determined * for an option, an error is returned. * * The values for dbname and user are treated special in conninfo_parse. * If the Compiled-in resource is specified as a NULL value, the * user is determined by fe_getauthname() and for dbname the user * name is copied. * * The Label and Disp-Char entries are provided for applications that * want to use PQconndefaults() to create a generic database connection * dialog. Disp-Char is defined as follows: *	   ""		Normal input field * ---------- */static PQconninfoOption PQconninfoOptions[] = {/* ----------------------------------------------------------------- *//*	  Option-name		Environment-Var Compiled-in		Current value	*//*						Label							Disp-Char		*//* ----------------- --------------- --------------- --------------- */	/* "authtype" is ignored as it is no longer used. */	{"authtype", "PGAUTHTYPE", DefaultAuthtype, NULL,	"Database-Authtype", "", 20},	{"user", "PGUSER", NULL, NULL,	"Database-User", "", 20},	{"password", "PGPASSWORD", DefaultPassword, NULL,	"Database-Password", "", 20},	{"dbname", "PGDATABASE", NULL, NULL,	"Database-Name", "", 20},	{"host", "PGHOST", NULL, NULL,	"Database-Host", "", 40},	{"port", "PGPORT", DEF_PGPORT, NULL,	"Database-Port", "", 6},	{"tty", "PGTTY", DefaultTty, NULL,	"Backend-Debug-TTY", "D", 40},	{"options", "PGOPTIONS", DefaultOption, NULL,	"Backend-Debug-Options", "D", 40},/* ----------------- --------------- --------------- --------------- */	{NULL, NULL, NULL, NULL,	NULL, NULL, 0}};static struct EnvironmentOptions{	const char *envName,			   *pgName;}			EnvironmentOptions[] ={	/* common user-interface settings */	{		"PGDATESTYLE", "datestyle"	},	{		"PGTZ", "timezone"	},#ifdef MULTIBYTE	{		"PGCLIENTENCODING", "client_encoding"	},#endif	/* internal performance-related settings */	{		"PGCOSTHEAP", "cost_heap"	},	{		"PGCOSTINDEX", "cost_index"	},	{		"PGGEQO", "geqo"	},	{		NULL	}};/* ---------------- *		PQconnectdb * * establishes a connection to a postgres backend through the postmaster * using connection information in a string. * * The conninfo string is a list of * *	   option = value * * definitions. Value might be a single value containing no whitespaces * or a single quoted string. If a single quote should appear everywhere * in the value, it must be escaped with a backslash like \' * * Returns a PGconn* which is needed for all subsequent libpq calls * if the status field of the connection returned is CONNECTION_BAD, * then some fields may be null'ed out instead of having valid values * ---------------- */PGconn *PQconnectdb(const char *conninfo){	PGconn	   *conn;	char	   *tmp;	/* ----------	 * Allocate memory for the conn structure	 * ----------	 */	conn = makeEmptyPGconn();	if (conn == NULL)		return (PGconn *) NULL;	/* ----------	 * Parse the conninfo string and save settings in conn structure	 * ----------	 */	if (conninfo_parse(conninfo, conn->errorMessage) < 0)	{		conn->status = CONNECTION_BAD;		conninfo_free();		return conn;	}	tmp = conninfo_getval("host");	conn->pghost = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("port");	conn->pgport = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("tty");	conn->pgtty = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("options");	conn->pgoptions = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("dbname");	conn->dbName = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("user");	conn->pguser = tmp ? strdup(tmp) : NULL;	tmp = conninfo_getval("password");	conn->pgpass = tmp ? strdup(tmp) : NULL;	/* ----------	 * Free the connection info - all is in conn now	 * ----------	 */	conninfo_free();	/* ----------	 * Connect to the database	 * ----------	 */	conn->status = connectDB(conn);	return conn;}/* ---------------- *		PQconndefaults * * Parse an empty string like PQconnectdb() would do and return the * address of the connection options structure. Using this function * an application might determine all possible options and their * current default values. * ---------------- */PQconninfoOption *PQconndefaults(void){	char		errorMessage[ERROR_MSG_LENGTH];	conninfo_parse("", errorMessage);	return PQconninfoOptions;}/* ---------------- *		PQsetdbLogin * * establishes a connection to a postgres backend through the postmaster * at the specified host and port. * * returns a PGconn* which is needed for all subsequent libpq calls * if the status field of the connection returned is CONNECTION_BAD, * then some fields may be null'ed out instead of having valid values * *	Uses these environment variables: * *	  PGHOST	   identifies host to which to connect if <pghost> argument *				   is NULL or a null string. * *	  PGPORT	   identifies TCP port to which to connect if <pgport> argument *				   is NULL or a null string. * *	  PGTTY		   identifies tty to which to send messages if <pgtty> argument *				   is NULL or a null string. * *	  PGOPTIONS    identifies connection options if <pgoptions> argument is *				   NULL or a null string. * *	  PGUSER	   Postgres username to associate with the connection. * *	  PGPASSWORD   The user's password. * *	  PGDATABASE   name of database to which to connect if <pgdatabase> *				   argument is NULL or a null string * *	  None of the above need be defined.  There are defaults for all of them. * * To support "delimited identifiers" for database names, only convert * the database name to lower case if it is not surrounded by double quotes. * Otherwise, strip the double quotes but leave the reset of the string intact. * - thomas 1997-11-08 * * ---------------- */PGconn *PQsetdbLogin(const char *pghost, const char *pgport, const char *pgoptions, const char *pgtty, const char *dbName, const char *login, const char *pwd){	PGconn	   *conn;	char	   *tmp;	/* An error message from some service we call. */	bool		error = FALSE;	/* We encountered an error that prevents successful completion */	int			i;	conn = makeEmptyPGconn();	if (conn == NULL)		return (PGconn *) NULL;	if ((pghost == NULL) || pghost[0] == '\0')	{		if ((tmp = getenv("PGHOST")) != NULL)			conn->pghost = strdup(tmp);	}	else		conn->pghost = strdup(pghost);	if ((pgport == NULL) || pgport[0] == '\0')	{		if ((tmp = getenv("PGPORT")) == NULL)			tmp = DEF_PGPORT;		conn->pgport = strdup(tmp);	}	else		conn->pgport = strdup(pgport);	if ((pgtty == NULL) || pgtty[0] == '\0')	{		if ((tmp = getenv("PGTTY")) == NULL)			tmp = DefaultTty;		conn->pgtty = strdup(tmp);	}	else		conn->pgtty = strdup(pgtty);	if ((pgoptions == NULL) || pgoptions[0] == '\0')	{		if ((tmp = getenv("PGOPTIONS")) == NULL)			tmp = DefaultOption;		conn->pgoptions = strdup(tmp);	}	else		conn->pgoptions = strdup(pgoptions);	if (login)		conn->pguser = strdup(login);	else if ((tmp = getenv("PGUSER")) != NULL)		conn->pguser = strdup(tmp);	else		conn->pguser = fe_getauthname(conn->errorMessage);	if (conn->pguser == NULL)	{		error = TRUE;		sprintf(conn->errorMessage,				"FATAL: PQsetdbLogin(): Unable to determine a Postgres username!\n");	}	if (pwd)		conn->pgpass = strdup(pwd);	else if ((tmp = getenv("PGPASSWORD")) != NULL)		conn->pgpass = strdup(tmp);	else		conn->pgpass = strdup(DefaultPassword);	if ((dbName == NULL) || dbName[0] == '\0')	{		if ((tmp = getenv("PGDATABASE")) != NULL)			conn->dbName = strdup(tmp);		else if (conn->pguser)			conn->dbName = strdup(conn->pguser);	}	else		conn->dbName = strdup(dbName);	if (conn->dbName)	{		/*		 * if the database name is surrounded by double-quotes, then don't		 * convert case		 */		if (*conn->dbName == '"')		{			strcpy(conn->dbName, conn->dbName + 1);			conn->dbName[strlen(conn->dbName) - 1] = '\0';		}		else			for (i = 0; conn->dbName[i]; i++)				if (isascii((unsigned char) conn->dbName[i]) &&					isupper(conn->dbName[i]))					conn->dbName[i] = tolower(conn->dbName[i]);	}	if (error)		conn->status = CONNECTION_BAD;	else		conn->status = connectDB(conn);	return conn;}/* * update_db_info - * get all additional infos out of dbName * */static intupdate_db_info(PGconn *conn){	char	   *tmp,			   *old = conn->dbName;	if (strchr(conn->dbName, '@') != NULL)	{		/* old style: dbname[@server][:port] */		tmp = strrchr(conn->dbName, ':');		if (tmp != NULL)		/* port number given */		{			conn->pgport = strdup(tmp + 1);			*tmp = '\0';		}		tmp = strrchr(conn->dbName, '@');		if (tmp != NULL)		/* host name given */		{			conn->pghost = strdup(tmp + 1);			*tmp = '\0';		}		conn->dbName = strdup(old);		free(old);	}	else	{		int			offset;		/*		 * only allow protocols tcp and unix		 */		if (strncmp(conn->dbName, "tcp:", 4) == 0)			offset = 4;		else if (strncmp(conn->dbName, "unix:", 5) == 0)			offset = 5;		else			return 0;		if (strncmp(conn->dbName + offset, "postgresql://", strlen("postgresql://")) == 0)		{			/*			 * new style:			 * <tcp|unix>:postgresql://server[:port][/dbname][?options]			 */			offset += strlen("postgresql://");			tmp = strrchr(conn->dbName + offset, '?');			if (tmp != NULL)	/* options given */			{				conn->pgoptions = strdup(tmp + 1);				*tmp = '\0';			}			tmp = strrchr(conn->dbName + offset, '/');			if (tmp != NULL)	/* database name given */			{				conn->dbName = strdup(tmp + 1);				*tmp = '\0';			}			else			{				if ((tmp = getenv("PGDATABASE")) != NULL)					conn->dbName = strdup(tmp);				else if (conn->pguser)					conn->dbName = strdup(conn->pguser);			}			tmp = strrchr(old + offset, ':');			if (tmp != NULL)	/* port number given */			{				conn->pgport = strdup(tmp + 1);				*tmp = '\0';			}			if (strncmp(old, "unix:", 5) == 0)			{				conn->pghost = NULL;				if (strcmp(old + offset, "localhost") != 0)				{					(void) sprintf(conn->errorMessage,								   "connectDB() -- non-tcp access only possible on localhost\n");					return 1;				}			}			else				conn->pghost = strdup(old + offset);			free(old);		}	}	return 0;}/* * connectDB - * make a connection to the backend so it is ready to receive queries. * return CONNECTION_OK if successful, CONNECTION_BAD if not. * */static ConnStatusTypeconnectDB(PGconn *conn){	PGresult   *res;	struct hostent *hp;	StartupPacket sp;	AuthRequest areq;

⌨️ 快捷键说明

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