aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/initdb/Makefile3
-rw-r--r--src/bin/initdb/initdb.c43
-rw-r--r--src/fe_utils/string_utils.c17
3 files changed, 46 insertions, 17 deletions
diff --git a/src/bin/initdb/Makefile b/src/bin/initdb/Makefile
index 094c8945c96..531cc979a48 100644
--- a/src/bin/initdb/Makefile
+++ b/src/bin/initdb/Makefile
@@ -18,6 +18,9 @@ include $(top_builddir)/src/Makefile.global
override CPPFLAGS := -DFRONTEND -I$(libpq_srcdir) -I$(top_srcdir)/src/timezone $(CPPFLAGS)
+# note: we need libpq only because fe_utils does
+LDFLAGS += -L$(top_builddir)/src/fe_utils -lpgfeutils $(libpq_pgport)
+
# use system timezone data?
ifneq (,$(with_system_tzdata))
override CPPFLAGS += '-DSYSTEMTZDIR="$(with_system_tzdata)"'
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index a978bbc328a..aad6ba5639f 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 */
@@ -331,14 +332,6 @@ do { \
output_failed = true, output_errno = errno; \
} while (0)
-#ifndef WIN32
-#define QUOTE_PATH ""
-#define DIR_SEP "/"
-#else
-#define QUOTE_PATH "\""
-#define DIR_SEP "\\"
-#endif
-
static char *
escape_quotes(const char *src)
{
@@ -3359,7 +3352,8 @@ main(int argc, char *argv[])
int c;
int option_index;
char *effective_user;
- char bin_dir[MAXPGPATH];
+ PQExpBuffer start_db_cmd;
+ char pg_ctl_path[MAXPGPATH];
/*
* Ensure that buffering behavior of stdout and stderr matches what it is
@@ -3587,14 +3581,33 @@ main(int argc, char *argv[])
if (authwarning != NULL)
fprintf(stderr, "%s", authwarning);
- /* Get directory specification used to start this executable */
- strlcpy(bin_dir, argv[0], sizeof(bin_dir));
- get_parent_directory(bin_dir);
+ /*
+ * Build up a shell command to tell the user how to start the server
+ */
+ start_db_cmd = createPQExpBuffer();
+
+ /* Get directory specification used to start initdb ... */
+ strlcpy(pg_ctl_path, argv[0], sizeof(pg_ctl_path));
+ canonicalize_path(pg_ctl_path);
+ get_parent_directory(pg_ctl_path);
+ /* ... and tag on pg_ctl instead */
+ join_path_components(pg_ctl_path, pg_ctl_path, "pg_ctl");
+
+ /* path to pg_ctl, properly quoted */
+ appendShellString(start_db_cmd, pg_ctl_path);
+
+ /* add -D switch, with properly quoted data directory */
+ appendPQExpBufferStr(start_db_cmd, " -D ");
+ appendShellString(start_db_cmd, pgdata_native);
+
+ /* add suggested -l switch and "start" command */
+ appendPQExpBufferStr(start_db_cmd, " -l logfile start");
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);
+ " %s\n\n"),
+ start_db_cmd->data);
+
+ destroyPQExpBuffer(start_db_cmd);
return 0;
}
diff --git a/src/fe_utils/string_utils.c b/src/fe_utils/string_utils.c
index 2c566b1ad75..edbc869e453 100644
--- a/src/fe_utils/string_utils.c
+++ b/src/fe_utils/string_utils.c
@@ -418,7 +418,7 @@ appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length,
/*
* Append the given string to the shell command being built in the buffer,
- * with suitable shell-style quoting to create exactly one argument.
+ * with shell-style quoting as needed to create exactly one argument.
*
* Forbid LF or CR characters, which have scant practical use beyond designing
* security breaches. The Windows command shell is unusable as a conduit for
@@ -429,8 +429,22 @@ appendByteaLiteral(PQExpBuffer buf, const unsigned char *str, size_t length,
void
appendShellString(PQExpBuffer buf, const char *str)
{
+#ifdef WIN32
+ int backslash_run_length = 0;
+#endif
const char *p;
+ /*
+ * Don't bother with adding quotes if the string is nonempty and clearly
+ * contains only safe characters.
+ */
+ if (*str != '\0' &&
+ strspn(str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_./:") == strlen(str))
+ {
+ appendPQExpBufferStr(buf, str);
+ return;
+ }
+
#ifndef WIN32
appendPQExpBufferChar(buf, '\'');
for (p = str; *p; p++)
@@ -450,7 +464,6 @@ appendShellString(PQExpBuffer buf, const char *str)
}
appendPQExpBufferChar(buf, '\'');
#else /* WIN32 */
- int backslash_run_length = 0;
/*
* A Windows system() argument experiences two layers of interpretation.