*** a/doc/src/sgml/ref/pg_basebackup.sgml
--- b/doc/src/sgml/ref/pg_basebackup.sgml
***************
*** 357,362 **** PostgreSQL documentation
--- 357,375 ----
     <para>
      The following command-line options control the database connection parameters.
  
+ 	<variablelist>
+      <varlistentry>
+       <term><option>-C <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These option can be used along with other user supplied options.
+         In case of conflicting option user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
      <variablelist>
       <varlistentry>
        <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
*** a/doc/src/sgml/ref/pg_receivexlog.sgml
--- b/doc/src/sgml/ref/pg_receivexlog.sgml
***************
*** 121,126 **** PostgreSQL documentation
--- 121,139 ----
     <para>
      The following command-line options control the database connection parameters.
  
+ 	<variablelist>
+      <varlistentry>
+       <term><option>-C <replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <term><option>--connection-string=<replaceable class="parameter">"OPTIONS"</replaceable></option></term>
+       <listitem>
+        <para>
+         Specifies connection string options, used for connecting to server.
+         These option can be used along with other user supplied options.
+         In case of conflicting option user supplied option is choosen.
+        </para>
+       </listitem>
+      </varlistentry>
+ 
      <variablelist>
       <varlistentry>
        <term><option>-h <replaceable class="parameter">host</replaceable></option></term>
*** a/src/bin/pg_basebackup/pg_basebackup.c
--- b/src/bin/pg_basebackup/pg_basebackup.c
***************
*** 126,131 **** usage(void)
--- 126,132 ----
  	printf(_("  -V, --version          output version information, then exit\n"));
  	printf(_("  -?, --help             show this help, then exit\n"));
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -C, --connection-string=\"OPTIONS\" Connect to server using OPTIONS\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"
***************
*** 1104,1125 **** ReceiveAndUnpackTarFile(PGconn *conn, PGresult *res, int rownum)
  }
  
  /*
-  * Escape single quotes used in connection parameters
-  */
- static char *
- escape_quotes(const char *src)
- {
- 	char	   *result = escape_single_quotes_ascii(src);
- 
- 	if (!result)
- 	{
- 		fprintf(stderr, _("%s: out of memory\n"), progname);
- 		exit(1);
- 	}
- 	return result;
- }
- 
- /*
   * Create a recovery.conf file in memory using a PQExpBuffer
   */
  static void
--- 1105,1110 ----
***************
*** 1532,1537 **** main(int argc, char **argv)
--- 1517,1523 ----
  		{"pgdata", required_argument, NULL, 'D'},
  		{"format", required_argument, NULL, 'F'},
  		{"checkpoint", required_argument, NULL, 'c'},
+ 		{"connection-string", required_argument, NULL, 'C'},
  		{"write-recovery-conf", no_argument, NULL, 'R'},
  		{"xlog", no_argument, NULL, 'x'},
  		{"xlog-method", required_argument, NULL, 'X'},
***************
*** 1570,1576 **** main(int argc, char **argv)
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:c:h:p:U:s:wWvP",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
--- 1556,1562 ----
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:F:RxX:l:zZ:C:c:h:p:U:s:wWvP",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
***************
*** 1661,1666 **** main(int argc, char **argv)
--- 1647,1655 ----
  					exit(1);
  				}
  				break;
+ 			case 'C':
+ 				connection_string = pg_strdup(optarg);
+ 				break;
  			case 'h':
  				dbhost = pg_strdup(optarg);
  				break;
*** a/src/bin/pg_basebackup/pg_receivexlog.c
--- b/src/bin/pg_basebackup/pg_receivexlog.c
***************
*** 58,63 **** usage(void)
--- 58,64 ----
  	printf(_("  -V, --version          output version information, then exit\n"));
  	printf(_("  -?, --help             show this help, then exit\n"));
  	printf(_("\nConnection options:\n"));
+ 	printf(_("  -C, --connection-string=\"OPTIONS\" Connect to server using OPTIONS\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"
***************
*** 305,310 **** main(int argc, char **argv)
--- 306,312 ----
  	static struct option long_options[] = {
  		{"help", no_argument, NULL, '?'},
  		{"version", no_argument, NULL, 'V'},
+ 		{"connection-string", required_argument, NULL, 'C'},
  		{"directory", required_argument, NULL, 'D'},
  		{"host", required_argument, NULL, 'h'},
  		{"port", required_argument, NULL, 'p'},
***************
*** 338,348 **** main(int argc, char **argv)
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "D:h:p:U:s:nwWv",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
  			case 'D':
  				basedir = pg_strdup(optarg);
  				break;
--- 340,353 ----
  		}
  	}
  
! 	while ((c = getopt_long(argc, argv, "C:D:h:p:U:s:nwWv",
  							long_options, &option_index)) != -1)
  	{
  		switch (c)
  		{
+ 			case 'C':
+ 				connection_string = pg_strdup(optarg);
+ 				break;
  			case 'D':
  				basedir = pg_strdup(optarg);
  				break;
*** a/src/bin/pg_basebackup/streamutil.c
--- b/src/bin/pg_basebackup/streamutil.c
***************
*** 24,29 **** char	   *dbport = NULL;
--- 24,47 ----
  int			dbgetpassword = 0;	/* 0=auto, -1=never, 1=always */
  static char *dbpassword = NULL;
  PGconn	   *conn = NULL;
+ char	   *connection_string = NULL;
+ 
+ 
+ /*
+  * Escape single quotes used in connection parameters
+  */
+ char *
+ escape_quotes(const char *src)
+ {
+ 	char	   *result = escape_single_quotes_ascii(src);
+ 
+ 	if (!result)
+ 	{
+ 		fprintf(stderr, _("%s: out of memory\n"), progname);
+ 		exit(1);
+ 	}
+ 	return result;
+ }
  
  /*
   * strdup() and malloc() replacements that print an error and exit
***************
*** 71,119 **** PGconn *
  GetConnection(void)
  {
  	PGconn	   *tmpconn;
- 	int			argcount = 4;	/* dbname, replication, fallback_app_name,
- 								 * password */
- 	int			i;
- 	const char **keywords;
- 	const char **values;
  	char	   *password = NULL;
  	const char *tmpparam;
! 
! 	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";
! 		values[i] = dbhost;
! 		i++;
! 	}
  	if (dbuser)
! 	{
! 		keywords[i] = "user";
! 		values[i] = dbuser;
! 		i++;
! 	}
  	if (dbport)
! 	{
! 		keywords[i] = "port";
! 		values[i] = dbport;
! 		i++;
! 	}
  
  	while (true)
  	{
--- 89,122 ----
  GetConnection(void)
  {
  	PGconn	   *tmpconn;
  	char	   *password = NULL;
  	const char *tmpparam;
! 	char		conninfo[MAXCONNINFO];
! 	int			conn_len = 0;
! 	char		*conninfo_ptr = conninfo;
! 
! 	/*
! 	 * Connect using deliberately undocumented parameter: replication. The
! 	 * database name is ignored by the server in replication mode.
! 	 */
! 	conn_len += snprintf(conninfo_ptr, (sizeof(conninfo) - conn_len),
! 	"%s dbname=replication replication=true fallback_application_name='%s' ",
! 	connection_string ? connection_string : "", progname);
! 
! 	/*
! 	 * Extra options provided are added at the end of connection string.
! 	 */
  	if (dbhost)
! 		conn_len += snprintf((conninfo_ptr + conn_len), (sizeof(conninfo) - conn_len),
! 					"host='%s' ", dbhost);
! 
  	if (dbuser)
! 		conn_len += snprintf((conninfo_ptr + conn_len), (sizeof(conninfo) - conn_len),
! 					"user=%s ", dbuser);
! 
  	if (dbport)
! 		conn_len += snprintf((conninfo_ptr + conn_len), (sizeof(conninfo) - conn_len),
! 					"port=%s ", dbport);
  
  	while (true)
  	{
***************
*** 127,144 **** 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;
  			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;
  		}
  
! 		tmpconn = PQconnectdbParams(keywords, values, true);
  
  		/*
  		 * If there is too little memory even to allocate the PGconn object
--- 130,147 ----
  			 * meaning this is the call for a second session to the same
  			 * database, so just forcibly reuse that password.
  			 */
! 			snprintf((conninfo_ptr + conn_len), (sizeof(conninfo) - conn_len),
! 						"password='%s' ", escape_quotes(dbpassword));
  			dbgetpassword = -1; /* Don't try again if this fails */
  		}
  		else if (dbgetpassword == 1)
  		{
  			password = simple_prompt(_("Password: "), 100, false);
! 			snprintf((conninfo_ptr + conn_len), (sizeof(conninfo) - conn_len),
! 						"password='%s' ", escape_quotes(password));
  		}
  
! 		tmpconn = PQconnectdb(conninfo);
  
  		/*
  		 * If there is too little memory even to allocate the PGconn object
***************
*** 165,179 **** GetConnection(void)
  			fprintf(stderr, _("%s: could not connect to server: %s\n"),
  					progname, PQerrorMessage(tmpconn));
  			PQfinish(tmpconn);
- 			free(values);
- 			free(keywords);
  			return NULL;
  		}
  
- 		/* Connection ok! */
- 		free(values);
- 		free(keywords);
- 
  		/*
  		 * Ensure we have the same value of integer timestamps as the server
  		 * we are connecting to.
--- 168,176 ----
*** a/src/bin/pg_basebackup/streamutil.h
--- b/src/bin/pg_basebackup/streamutil.h
***************
*** 5,10 **** extern char *dbhost;
--- 5,11 ----
  extern char *dbuser;
  extern char *dbport;
  extern int	dbgetpassword;
+ extern char	*connection_string;
  
  /* Connection kept global so we can disconnect easily */
  extern PGconn *conn;
***************
*** 15,20 **** extern PGconn *conn;
--- 16,22 ----
  	exit(code);									\
  	}
  
+ extern char *escape_quotes(const char *src);
  
  extern char *pg_strdup(const char *s);
  extern void *pg_malloc0(size_t size);
*** a/src/include/pg_config_manual.h
--- b/src/include/pg_config_manual.h
***************
*** 200,205 ****
--- 200,211 ----
  #endif
  
  /*
+  * MAXCONNINFO: maximum size of a connection string.
+  */
+ #define MAXCONNINFO		1024
+ 
+ 
+ /*
   *------------------------------------------------------------------------
   * The following symbols are for enabling debugging code, not for
   * controlling user-visible features or resource limits.
*** a/src/include/replication/walreceiver.h
--- b/src/include/replication/walreceiver.h
***************
*** 23,35 **** extern int	wal_receiver_status_interval;
  extern int	wal_receiver_timeout;
  extern bool hot_standby_feedback;
  
- /*
-  * MAXCONNINFO: maximum size of a connection string.
-  *
-  * XXX: Should this move to pg_config_manual.h?
-  */
- #define MAXCONNINFO		1024
- 
  /* Can we allow the standby to accept replication connection from another standby? */
  #define AllowCascadeReplication() (EnableHotStandby && max_wal_senders > 0)
  
--- 23,28 ----
*** a/src/interfaces/libpq/fe-connect.c
--- b/src/interfaces/libpq/fe-connect.c
***************
*** 4216,4224 **** conninfo_parse(const char *conninfo, PQExpBuffer errorMessage,
  				}
  				if (*cp == '\'')
  				{
- 					*cp2 = '\0';
  					cp++;
! 					break;
  				}
  				*cp2++ = *cp++;
  			}
--- 4216,4227 ----
  				}
  				if (*cp == '\'')
  				{
  					cp++;
! 					if (*cp != '\'')
! 					{
! 						*cp2 = '\0';
! 						break;
! 					}
  				}
  				*cp2++ = *cp++;
  			}
