aboutsummaryrefslogtreecommitdiff
path: root/src/bin/pg_basebackup/streamutil.c
diff options
context:
space:
mode:
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-25 14:48:27 +0200
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>2013-02-25 14:59:33 +0200
commitaa05c37e823a41056273e73f6b3d168009a67c3f (patch)
tree984b4da2ff71ffc6a4df286567428eba65cb92de /src/bin/pg_basebackup/streamutil.c
parent786170d74f30bc8d3017149dc444f3f3e29029a7 (diff)
downloadpostgresql-aa05c37e823a41056273e73f6b3d168009a67c3f.tar.gz
postgresql-aa05c37e823a41056273e73f6b3d168009a67c3f.zip
Add -d option to pg_basebackup and pg_receivexlog, for connection string.
Without this, there's no way to pass arbitrary libpq connection parameters to these applications. It's a bit strange that the option is called -d/--dbname, when in fact you can *not* pass a database name in it, but it's consistent with other client applications where a connection string is also passed using -d. Original patch by Amit Kapila, heavily modified by me.
Diffstat (limited to 'src/bin/pg_basebackup/streamutil.c')
-rw-r--r--src/bin/pg_basebackup/streamutil.c87
1 files changed, 64 insertions, 23 deletions
diff --git a/src/bin/pg_basebackup/streamutil.c b/src/bin/pg_basebackup/streamutil.c
index 8a43c4bad1d..a878dd43451 100644
--- a/src/bin/pg_basebackup/streamutil.c
+++ b/src/bin/pg_basebackup/streamutil.c
@@ -18,6 +18,7 @@
#include <string.h>
const char *progname;
+char *connection_string = NULL;
char *dbhost = NULL;
char *dbuser = NULL;
char *dbport = NULL;
@@ -34,31 +35,67 @@ PGconn *
GetConnection(void)
{
PGconn *tmpconn;
- int argcount = 4; /* dbname, replication, fallback_app_name,
- * password */
+ int argcount = 7; /* dbname, replication, fallback_app_name,
+ * host, user, port, password */
int i;
const char **keywords;
const char **values;
char *password = NULL;
const char *tmpparam;
+ PQconninfoOption *conn_opts = NULL;
+ PQconninfoOption *conn_opt;
+ char *err_msg = NULL;
+
+ /*
+ * Merge the connection info inputs given in form of connection string,
+ * options and default values (dbname=replication, replication=true,
+ * etc.)
+ */
+ i = 0;
+ if (connection_string)
+ {
+ conn_opts = PQconninfoParse(connection_string, &err_msg);
+ if (conn_opts == NULL)
+ {
+ fprintf(stderr, "%s: %s\n", progname, err_msg);
+ return NULL;
+ }
+
+ for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
+ {
+ if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
+ argcount++;
+ }
+
+ keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
+ values = pg_malloc0((argcount + 1) * sizeof(*values));
+
+ for (conn_opt = conn_opts; conn_opt->keyword != NULL; conn_opt++)
+ {
+ if (conn_opt->val != NULL && conn_opt->val[0] != '\0')
+ {
+ keywords[i] = conn_opt->keyword;
+ values[i] = conn_opt->val;
+ i++;
+ }
+ }
+ }
+ else
+ {
+ keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
+ values = pg_malloc0((argcount + 1) * sizeof(*values));
+ }
+
+ keywords[i] = "dbname";
+ values[i] = "replication";
+ i++;
+ keywords[i] = "replication";
+ values[i] = "true";
+ i++;
+ keywords[i] = "fallback_application_name";
+ values[i] = progname;
+ i++;
- if (dbhost)
- argcount++;
- if (dbuser)
- argcount++;
- if (dbport)
- argcount++;
-
- keywords = pg_malloc0((argcount + 1) * sizeof(*keywords));
- values = pg_malloc0((argcount + 1) * sizeof(*values));
-
- keywords[0] = "dbname";
- values[0] = "replication";
- keywords[1] = "replication";
- values[1] = "true";
- keywords[2] = "fallback_application_name";
- values[2] = progname;
- i = 3;
if (dbhost)
{
keywords[i] = "host";
@@ -90,15 +127,15 @@ GetConnection(void)
* meaning this is the call for a second session to the same
* database, so just forcibly reuse that password.
*/
- keywords[argcount - 1] = "password";
- values[argcount - 1] = dbpassword;
+ keywords[i] = "password";
+ values[i] = dbpassword;
dbgetpassword = -1; /* Don't try again if this fails */
}
else if (dbgetpassword == 1)
{
password = simple_prompt(_("Password: "), 100, false);
- keywords[argcount - 1] = "password";
- values[argcount - 1] = password;
+ keywords[i] = "password";
+ values[i] = password;
}
tmpconn = PQconnectdbParams(keywords, values, true);
@@ -130,12 +167,16 @@ GetConnection(void)
PQfinish(tmpconn);
free(values);
free(keywords);
+ if (conn_opts)
+ PQconninfoFree(conn_opts);
return NULL;
}
/* Connection ok! */
free(values);
free(keywords);
+ if (conn_opts)
+ PQconninfoFree(conn_opts);
/*
* Ensure we have the same value of integer timestamps as the server