From d4b3d9468a3e183f0906e051b3dbc08d5b3e6bca Mon Sep 17 00:00:00 2001
From: ryanfmurphy <ryanfmurphy@gmail.com>
Date: Wed, 17 Aug 2016 10:19:12 -0500
Subject: [PATCH] initdb: quote shell args in final pg_ctl command

    fix issue when running initdb

    at the end of a successful initdb it says:

    Success. You can now start the database server using:
        /path/to/pg_ctl -D /some/path/to/data -l logfile start

    but this command will not work if the data directory contains a space
    therefore, correctly escape shell arguments using appendShellString

        '/path/to/pg_ctl' -D '/some/path/to/data' -l logfile start
---
 src/bin/initdb/Makefile |  3 +++
 src/bin/initdb/initdb.c | 40 ++++++++++++++++++++++++++++++++++------
 2 files changed, 37 insertions(+), 6 deletions(-)

diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile
index 094c894..40aad66 100644
--- a/src/bin/initdb/Makefile
+++ b/src/bin/initdb/Makefile
@@ -16,6 +16,9 @@ subdir = src/bin/initdb
 top_builddir = ../../..
 include $(top_builddir)/src/Makefile.global
 
+# need fe_utils and lpq for PQExpBuffer for quoted shell string
+LDFLAGS += -L$(top_builddir)/src/fe_utils -lpgfeutils -lpq
+
 override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(CPPFLAGS)
 
 # use system timezone data?
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index 73cb7ee..d6317e4 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -67,6 +67,7 @@
 #include "getaddrinfo.h"
 #include "getopt_long.h"
 #include "miscadmin.h"
+#include "fe_utils/string_utils.h"
 
 
 /* Define PG_FLUSH_DATA_WORKS if we have an implementation for pg_flush_data */
@@ -332,10 +333,8 @@ do { \
 } while (0)
 
 #ifndef WIN32
-#define QUOTE_PATH	""
 #define DIR_SEP "/"
 #else
-#define QUOTE_PATH	"\""
 #define DIR_SEP "\\"
 #endif
 
@@ -3585,10 +3584,39 @@ main(int argc, char *argv[])
 	strlcpy(bin_dir, argv[0], sizeof(bin_dir));
 	get_parent_directory(bin_dir);
 
-	printf(_("\nSuccess. You can now start the database server using:\n\n"
-			 "    %s%s%spg_ctl%s -D %s%s%s -l logfile start\n\n"),
-	   QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
-		   QUOTE_PATH, pgdata_native, QUOTE_PATH);
+	/*
+	 * Build up a shell command to tell the user how to start the server
+	 * e.g.
+	 * '/path/to/pg_ctl' -D '/path/to/data_dir' -l logfile start
+	 */
+	{
+		PQExpBuffer start_db_cmd = createPQExpBuffer();
+
+		{ /* pg_ctl command w path, properly quoted */
+			PQExpBuffer pg_ctl_path = createPQExpBuffer();
+			printfPQExpBuffer(pg_ctl_path, "%s%spg_ctl",
+				bin_dir,
+				(strlen(bin_dir) > 0) ? DIR_SEP : ""
+			);
+			appendShellString(start_db_cmd, pg_ctl_path->data);
+			destroyPQExpBuffer(pg_ctl_path);
+		}
+
+		appendPQExpBufferStr(start_db_cmd, " -D ");
+
+		/* data dir, properly quoted */
+		appendShellString(start_db_cmd, pgdata_native);
+
+		appendPQExpBufferStr(start_db_cmd, " -l logfile");
+
+		appendPQExpBufferStr(start_db_cmd, " start");
+
+		printf(_("\nSuccess. You can now start the database server using:\n\n"
+				 "	  %s\n\n"),
+				start_db_cmd->data);
+
+		destroyPQExpBuffer(start_db_cmd);
+	}
 
 	return 0;
 }
-- 
2.5.4 (Apple Git-61)

