diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-25 14:48:27 +0200 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2013-02-25 14:59:33 +0200 |
commit | aa05c37e823a41056273e73f6b3d168009a67c3f (patch) | |
tree | 984b4da2ff71ffc6a4df286567428eba65cb92de /src/bin/pg_basebackup/streamutil.c | |
parent | 786170d74f30bc8d3017149dc444f3f3e29029a7 (diff) | |
download | postgresql-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.c | 87 |
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 |