aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/bin/pg_basebackup/pg_basebackup.c7
-rw-r--r--src/bin/pg_basebackup/pg_receivexlog.c7
-rw-r--r--src/bin/pg_basebackup/streamutil.c87
-rw-r--r--src/bin/pg_basebackup/streamutil.h1
4 files changed, 77 insertions, 25 deletions
diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c
index fb5a1bd1c19..2de03acabd6 100644
--- a/src/bin/pg_basebackup/pg_basebackup.c
+++ b/src/bin/pg_basebackup/pg_basebackup.c
@@ -126,6 +126,7 @@ usage(void)
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
+ printf(_(" -d, --dbname=CONNSTR connection string\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n"
@@ -1540,6 +1541,7 @@ main(int argc, char **argv)
{"gzip", no_argument, NULL, 'z'},
{"compress", required_argument, NULL, 'Z'},
{"label", required_argument, NULL, 'l'},
+ {"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
@@ -1572,7 +1574,7 @@ main(int argc, char **argv)
}
}
- while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP",
+ while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:d:c:h:p:U:s:wWvP",
long_options, &option_index)) != -1)
{
switch (c)
@@ -1663,6 +1665,9 @@ main(int argc, char **argv)
exit(1);
}
break;
+ case 'd':
+ connection_string = pg_strdup(optarg);
+ break;
case 'h':
dbhost = pg_strdup(optarg);
break;
diff --git a/src/bin/pg_basebackup/pg_receivexlog.c b/src/bin/pg_basebackup/pg_receivexlog.c
index 33dbc50389b..352ff353768 100644
--- a/src/bin/pg_basebackup/pg_receivexlog.c
+++ b/src/bin/pg_basebackup/pg_receivexlog.c
@@ -58,6 +58,7 @@ usage(void)
printf(_(" -V, --version output version information, then exit\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\nConnection options:\n"));
+ printf(_(" -d, --dbname=CONNSTR connection string\n"));
printf(_(" -h, --host=HOSTNAME database server host or socket directory\n"));
printf(_(" -p, --port=PORT database server port number\n"));
printf(_(" -s, --status-interval=INTERVAL\n"
@@ -306,6 +307,7 @@ main(int argc, char **argv)
{"help", no_argument, NULL, '?'},
{"version", no_argument, NULL, 'V'},
{"directory", required_argument, NULL, 'D'},
+ {"dbname", required_argument, NULL, 'd'},
{"host", required_argument, NULL, 'h'},
{"port", required_argument, NULL, 'p'},
{"username", required_argument, NULL, 'U'},
@@ -338,7 +340,7 @@ main(int argc, char **argv)
}
}
- while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
+ while ((c = getopt_long(argc, argv, "D:d:h:p:U:s:nwWv",
long_options, &option_index)) != -1)
{
switch (c)
@@ -346,6 +348,9 @@ main(int argc, char **argv)
case 'D':
basedir = pg_strdup(optarg);
break;
+ case 'd':
+ connection_string = pg_strdup(optarg);
+ break;
case 'h':
dbhost = pg_strdup(optarg);
break;
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
diff --git a/src/bin/pg_basebackup/streamutil.h b/src/bin/pg_basebackup/streamutil.h
index 4f5ff914e23..77d6b86ced3 100644
--- a/src/bin/pg_basebackup/streamutil.h
+++ b/src/bin/pg_basebackup/streamutil.h
@@ -1,6 +1,7 @@
#include "libpq-fe.h"
extern const char *progname;
+extern char *connection_string;
extern char *dbhost;
extern char *dbuser;
extern char *dbport;