aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_backup_db.c61
-rw-r--r--src/bin/pg_dump/pg_dumpall.c32
-rw-r--r--src/bin/psql/command.c29
-rw-r--r--src/bin/psql/startup.c43
-rw-r--r--src/bin/scripts/common.c32
-rw-r--r--src/interfaces/libpq/fe-connect.c115
-rw-r--r--src/interfaces/libpq/libpq-fe.h8
7 files changed, 266 insertions, 54 deletions
diff --git a/src/bin/pg_dump/pg_backup_db.c b/src/bin/pg_dump/pg_backup_db.c
index 1d72d6dd7e2..4aa10135bb0 100644
--- a/src/bin/pg_dump/pg_backup_db.c
+++ b/src/bin/pg_dump/pg_backup_db.c
@@ -5,7 +5,7 @@
* Implements the basic DB functions used by the archiver.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.85 2009/12/14 00:39:11 itagaki Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_backup_db.c,v 1.86 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -154,10 +154,34 @@ _connectDB(ArchiveHandle *AH, const char *reqdb, const char *requser)
do
{
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ die_horribly(AH, modulename, "out of memory\n");
+
+ keywords[0] = "host";
+ values[0] = PQhost(AH->connection);
+ keywords[1] = "port";
+ values[1] = PQport(AH->connection);
+ keywords[2] = "user";
+ values[2] = newuser;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = newdb;
+ keywords[5] = "fallback_application_name";
+ values[5] = progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
new_pass = false;
- newConn = PQsetdbLogin(PQhost(AH->connection), PQport(AH->connection),
- NULL, NULL, newdb,
- newuser, password);
+ newConn = PQconnectdbParams(keywords, values, true);
+
+ free(keywords);
+ free(values);
+
if (!newConn)
die_horribly(AH, modulename, "failed to reconnect to database\n");
@@ -237,9 +261,33 @@ ConnectDatabase(Archive *AHX,
*/
do
{
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ die_horribly(AH, modulename, "out of memory\n");
+
+ keywords[0] = "host";
+ values[0] = pghost;
+ keywords[1] = "port";
+ values[1] = pgport;
+ keywords[2] = "user";
+ values[2] = username;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = dbname;
+ keywords[5] = "fallback_application_name";
+ values[5] = progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
new_pass = false;
- AH->connection = PQsetdbLogin(pghost, pgport, NULL, NULL,
- dbname, username, password);
+ AH->connection = PQconnectdbParams(keywords, values, true);
+
+ free(keywords);
+ free(values);
if (!AH->connection)
die_horribly(AH, modulename, "failed to connect to database\n");
@@ -697,3 +745,4 @@ _isDQChar(unsigned char c, bool atStart)
else
return false;
}
+
diff --git a/src/bin/pg_dump/pg_dumpall.c b/src/bin/pg_dump/pg_dumpall.c
index 48084db12f8..f1d74574313 100644
--- a/src/bin/pg_dump/pg_dumpall.c
+++ b/src/bin/pg_dump/pg_dumpall.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.131 2010/01/06 03:34:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.132 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1618,8 +1618,36 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/
do
{
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ {
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+ exit(1);
+ }
+
+ keywords[0] = "host";
+ values[0] = pghost;
+ keywords[1] = "port";
+ values[1] = pgport;
+ keywords[2] = "user";
+ values[2] = pguser;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = dbname;
+ keywords[5] = "fallback_application_name";
+ values[5] = progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
new_pass = false;
- conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
+ conn = PQconnectdbParams(keywords, values, true);
+
+ free(keywords);
+ free(values);
if (!conn)
{
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 10f36dc22d4..74119fd29f0 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.213 2010/01/02 16:57:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/command.c,v 1.214 2010/02/05 03:09:05 joe Exp $
*/
#include "postgres_fe.h"
#include "command.h"
@@ -1213,7 +1213,7 @@ param_is_newly_set(const char *old_val, const char *new_val)
* Connects to a database with given parameters. If there exists an
* established connection, NULL values will be replaced with the ones
* in the current connection. Otherwise NULL will be passed for that
- * parameter to PQsetdbLogin(), so the libpq defaults will be used.
+ * parameter to PQconnectdbParams(), so the libpq defaults will be used.
*
* In interactive mode, if connection fails with the given parameters,
* the old connection will be kept.
@@ -1255,8 +1255,29 @@ do_connect(char *dbname, char *user, char *host, char *port)
while (true)
{
- n_conn = PQsetdbLogin(host, port, NULL, NULL,
- dbname, user, password);
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ keywords[0] = "host";
+ values[0] = host;
+ keywords[1] = "port";
+ values[1] = port;
+ keywords[2] = "user";
+ values[2] = user;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = dbname;
+ keywords[5] = "fallback_application_name";
+ values[5] = pset.progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
+ n_conn = PQconnectdbParams(keywords, values, true);
+
+ free(keywords);
+ free(values);
/* We can immediately discard the password -- no longer needed */
if (password)
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index b29c84fdaec..c45a869d92c 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2010, PostgreSQL Global Development Group
*
- * $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.159 2010/01/28 06:28:26 joe Exp $
+ * $PostgreSQL: pgsql/src/bin/psql/startup.c,v 1.160 2010/02/05 03:09:05 joe Exp $
*/
#include "postgres_fe.h"
@@ -90,8 +90,6 @@ main(int argc, char *argv[])
char *password = NULL;
char *password_prompt = NULL;
bool new_pass;
- const char *keywords[] = {"host","port","dbname","user",
- "password","application_name",NULL};
set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("psql"));
@@ -173,20 +171,31 @@ main(int argc, char *argv[])
/* loop until we have a password if requested by backend */
do
{
- const char *values[] = {
- options.host,
- options.port,
- (options.action == ACT_LIST_DB &&
- options.dbname == NULL) ? "postgres" : options.dbname,
- options.username,
- password,
- pset.progname,
- NULL
- };
-
- new_pass = false;
-
- pset.db = PQconnectdbParams(keywords, values);
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = pg_malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ keywords[0] = "host";
+ values[0] = options.host;
+ keywords[1] = "port";
+ values[1] = options.port;
+ keywords[2] = "user";
+ values[2] = options.username;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = (options.action == ACT_LIST_DB &&
+ options.dbname == NULL) ?
+ "postgres" : options.dbname;
+ keywords[5] = "fallback_application_name";
+ values[5] = pset.progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
+ new_pass = false;
+ pset.db = PQconnectdbParams(keywords, values, true);
+ free(keywords);
+ free(values);
if (PQstatus(pset.db) == CONNECTION_BAD &&
PQconnectionNeedsPassword(pset.db) &&
diff --git a/src/bin/scripts/common.c b/src/bin/scripts/common.c
index 27aafa102c4..026eb80a025 100644
--- a/src/bin/scripts/common.c
+++ b/src/bin/scripts/common.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.38 2010/01/02 16:58:00 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/scripts/common.c,v 1.39 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -108,8 +108,36 @@ connectDatabase(const char *dbname, const char *pghost, const char *pgport,
*/
do
{
+#define PARAMS_ARRAY_SIZE 7
+ const char **keywords = malloc(PARAMS_ARRAY_SIZE * sizeof(*keywords));
+ const char **values = malloc(PARAMS_ARRAY_SIZE * sizeof(*values));
+
+ if (!keywords || !values)
+ {
+ fprintf(stderr, _("%s: out of memory\n"), progname);
+ exit(1);
+ }
+
+ keywords[0] = "host";
+ values[0] = pghost;
+ keywords[1] = "port";
+ values[1] = pgport;
+ keywords[2] = "user";
+ values[2] = pguser;
+ keywords[3] = "password";
+ values[3] = password;
+ keywords[4] = "dbname";
+ values[4] = dbname;
+ keywords[5] = "fallback_application_name";
+ values[5] = progname;
+ keywords[6] = NULL;
+ values[6] = NULL;
+
new_pass = false;
- conn = PQsetdbLogin(pghost, pgport, NULL, NULL, dbname, pguser, password);
+ conn = PQconnectdbParams(keywords, values, true);
+
+ free(keywords);
+ free(values);
if (!conn)
{
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 048c438527b..994b70b1904 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.385 2010/01/28 06:28:26 joe Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.386 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -269,7 +269,7 @@ static PQconninfoOption *conninfo_parse(const char *conninfo,
PQExpBuffer errorMessage, bool use_defaults);
static PQconninfoOption *conninfo_array_parse(const char **keywords,
const char **values, PQExpBuffer errorMessage,
- bool use_defaults);
+ bool use_defaults, int expand_dbname);
static char *conninfo_getval(PQconninfoOption *connOptions,
const char *keyword);
static void defaultNoticeReceiver(void *arg, const PGresult *res);
@@ -336,9 +336,11 @@ pgthreadlock_t pg_g_threadlock = default_threadlock;
* call succeeded.
*/
PGconn *
-PQconnectdbParams(const char **keywords, const char **values)
+PQconnectdbParams(const char **keywords,
+ const char **values,
+ int expand_dbname)
{
- PGconn *conn = PQconnectStartParams(keywords, values);
+ PGconn *conn = PQconnectStartParams(keywords, values, expand_dbname);
if (conn && conn->status != CONNECTION_BAD)
(void) connectDBComplete(conn);
@@ -400,7 +402,9 @@ PQconnectdb(const char *conninfo)
* See PQconnectPoll for more info.
*/
PGconn *
-PQconnectStartParams(const char **keywords, const char **values)
+PQconnectStartParams(const char **keywords,
+ const char **values,
+ int expand_dbname)
{
PGconn *conn;
PQconninfoOption *connOptions;
@@ -416,7 +420,8 @@ PQconnectStartParams(const char **keywords, const char **values)
* Parse the conninfo arrays
*/
connOptions = conninfo_array_parse(keywords, values,
- &conn->errorMessage, true);
+ &conn->errorMessage,
+ true, expand_dbname);
if (connOptions == NULL)
{
conn->status = CONNECTION_BAD;
@@ -3729,16 +3734,53 @@ conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
* left in errorMessage.
* Defaults are supplied (from a service file, environment variables, etc)
* for unspecified options, but only if use_defaults is TRUE.
+ *
+ * If expand_dbname is non-zero, and the value passed for keyword "dbname"
+ * contains an "=", assume it is a conninfo string and process it,
+ * overriding any previously processed conflicting keywords. Subsequent
+ * keywords will take precedence, however.
*/
static PQconninfoOption *
conninfo_array_parse(const char **keywords, const char **values,
- PQExpBuffer errorMessage, bool use_defaults)
+ PQExpBuffer errorMessage, bool use_defaults,
+ int expand_dbname)
{
char *tmp;
PQconninfoOption *options;
+ PQconninfoOption *str_options = NULL;
PQconninfoOption *option;
int i = 0;
+ /*
+ * If expand_dbname is non-zero, check keyword "dbname"
+ * to see if val is actually a conninfo string
+ */
+ while(expand_dbname && keywords[i])
+ {
+ const char *pname = keywords[i];
+ const char *pvalue = values[i];
+
+ /* first find "dbname" if any */
+ if (strcmp(pname, "dbname") == 0)
+ {
+ /* next look for "=" in the value */
+ if (pvalue && strchr(pvalue, '='))
+ {
+ /*
+ * Must be a conninfo string, so parse it, but do not
+ * use defaults here -- those get picked up later.
+ * We only want to override for those parameters actually
+ * passed.
+ */
+ str_options = conninfo_parse(pvalue, errorMessage, false);
+ if (str_options == NULL)
+ return NULL;
+ }
+ break;
+ }
+ ++i;
+ }
+
/* Make a working copy of PQconninfoOptions */
options = malloc(sizeof(PQconninfoOptions));
if (options == NULL)
@@ -3749,6 +3791,7 @@ conninfo_array_parse(const char **keywords, const char **values,
}
memcpy(options, PQconninfoOptions, sizeof(PQconninfoOptions));
+ i = 0;
/* Parse the keywords/values arrays */
while(keywords[i])
{
@@ -3774,22 +3817,54 @@ conninfo_array_parse(const char **keywords, const char **values,
return NULL;
}
- /*
- * Store the value
- */
- if (option->val)
- free(option->val);
- option->val = strdup(pvalue);
- if (!option->val)
- {
- printfPQExpBuffer(errorMessage,
- libpq_gettext("out of memory\n"));
- PQconninfoFree(options);
- return NULL;
- }
+ /*
+ * If we are on the dbname parameter, and we have a parsed
+ * conninfo string, copy those parameters across, overriding
+ * any existing previous settings
+ */
+ if (strcmp(pname, "dbname") == 0 && str_options)
+ {
+ PQconninfoOption *str_option;
+
+ for (str_option = str_options; str_option->keyword != NULL; str_option++)
+ {
+ if (str_option->val != NULL)
+ {
+ int k;
+
+ for (k = 0; options[k].keyword; k++)
+ {
+ if (strcmp(options[k].keyword, str_option->keyword) == 0)
+ {
+ if (options[k].val)
+ free(options[k].val);
+ options[k].val = strdup(str_option->val);
+ break;
+ }
+ }
+ }
+ }
+ }
+ else
+ {
+ /*
+ * Store the value, overriding previous settings
+ */
+ if (option->val)
+ free(option->val);
+ option->val = strdup(pvalue);
+ if (!option->val)
+ {
+ printfPQExpBuffer(errorMessage,
+ libpq_gettext("out of memory\n"));
+ PQconninfoFree(options);
+ return NULL;
+ }
+ }
}
++i;
}
+ PQconninfoFree(str_options);
/*
* Stop here if caller doesn't want defaults filled in.
diff --git a/src/interfaces/libpq/libpq-fe.h b/src/interfaces/libpq/libpq-fe.h
index 5f59da0f753..c2698fe257e 100644
--- a/src/interfaces/libpq/libpq-fe.h
+++ b/src/interfaces/libpq/libpq-fe.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.150 2010/01/28 06:28:26 joe Exp $
+ * $PostgreSQL: pgsql/src/interfaces/libpq/libpq-fe.h,v 1.151 2010/02/05 03:09:05 joe Exp $
*
*-------------------------------------------------------------------------
*/
@@ -226,12 +226,14 @@ typedef struct pgresAttDesc
/* make a new client connection to the backend */
/* Asynchronous (non-blocking) */
extern PGconn *PQconnectStart(const char *conninfo);
-extern PGconn *PQconnectStartParams(const char **keywords, const char **values);
+extern PGconn *PQconnectStartParams(const char **keywords,
+ const char **values, int expand_dbname);
extern PostgresPollingStatusType PQconnectPoll(PGconn *conn);
/* Synchronous (blocking) */
extern PGconn *PQconnectdb(const char *conninfo);
-extern PGconn *PQconnectdbParams(const char **keywords, const char **values);
+extern PGconn *PQconnectdbParams(const char **keywords,
+ const char **values, int expand_dbname);
extern PGconn *PQsetdbLogin(const char *pghost, const char *pgport,
const char *pgoptions, const char *pgtty,
const char *dbName,