From 55903d487b0fd191cb23420ba2675c470f4567f3 Mon Sep 17 00:00:00 2001
From: Nikhil R Deshpande <nikhail@gmail.com>
Date: Fri, 25 Apr 2014 20:35:27 -0700
Subject: [PATCH] Fix initdb for path with whitespace and at char

initdb code invokes postgres backend to boostrap the database dir.
On win32, it has special consideration for handling paths with
whitespace and special chars (e.g. '@') when invoking system()
call (see comment for SYSTEMQUOTE in src/include/port.h).
But not for popen() call (which also invokes a shell specified by
COMSPEC env var, e.g. cmd.exe), this double-quoting is missing.
Executable path is already surrounded by double-quotes, but the
entire command line needs to be enclosed in double quotes too.

This patch adds those double quotes on win32 for entire command line
wherever backend_exec is invoked through popen(). Without this patch,
initdb fails to run when initdb path as both whitespaces and '@' char.
E.g. following command fails without this patch:
C:\>"C:\Program Files\user@company\Postgres\9.3\bin\initdb.exe" -D "c:\baz"
'C:\Program' is not recognized as an internal or external command,
operable program or batch file.

If initdb path has just whitespace or '@' char, but not both, it works fine.

---
 src/bin/initdb/initdb.c | 32 ++++++++++++++++----------------
 1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 5fc7291..a0ef27b 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1444,7 +1444,7 @@ bootstrap_template1(void)
 	unsetenv("PGCLIENTENCODING");
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" --boot -x1 %s %s %s",
+			 SYSTEMQUOTE "\"%s\" --boot -x1 %s %s %s" SYSTEMQUOTE,
 			 backend_exec,
 			 data_checksums ? "-k" : "",
 			 boot_options, talkargs);
@@ -1485,7 +1485,7 @@ setup_auth(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1563,7 +1563,7 @@ get_set_pwd(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1663,7 +1663,7 @@ setup_depend(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1696,7 +1696,7 @@ setup_sysviews(void)
 	 * We use -j here to avoid backslashing stuff in system_views.sql
 	 */
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s -j template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s -j template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1727,7 +1727,7 @@ setup_description(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1834,7 +1834,7 @@ setup_collation(void)
 
 #if defined(HAVE_LOCALE_T) && !defined(WIN32)
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -1973,7 +1973,7 @@ setup_conversion(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2011,7 +2011,7 @@ setup_dictionary(void)
 	 * We use -j here to avoid backslashing stuff
 	 */
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s -j template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s -j template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2062,7 +2062,7 @@ setup_privileges(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2125,7 +2125,7 @@ setup_schema(void)
 	 * We use -j here to avoid backslashing stuff in information_schema.sql
 	 */
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s -j template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s -j template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2142,7 +2142,7 @@ setup_schema(void)
 	PG_CMD_CLOSE;
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2176,7 +2176,7 @@ load_plpgsql(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2201,7 +2201,7 @@ vacuum_db(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2257,7 +2257,7 @@ make_template0(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
@@ -2289,7 +2289,7 @@ make_postgres(void)
 	fflush(stdout);
 
 	snprintf(cmd, sizeof(cmd),
-			 "\"%s\" %s template1 >%s",
+			 SYSTEMQUOTE "\"%s\" %s template1 >%s" SYSTEMQUOTE,
 			 backend_exec, backend_options,
 			 DEVNULL);
 
-- 
1.7.11.msysgit.1

