ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/external/subpack/libs/postgresql/Makefile b/external/subpack/libs/postgresql/Makefile
new file mode 100644
index 0000000..f0cd1b2
--- /dev/null
+++ b/external/subpack/libs/postgresql/Makefile
@@ -0,0 +1,257 @@
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=postgresql
+PKG_VERSION:=15.6
+PKG_RELEASE:=1
+PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
+PKG_LICENSE:=PostgreSQL
+PKG_CPE_ID:=cpe:/a:postgresql:postgresql
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=\
+ https://ftp.postgresql.org/pub/source/v$(PKG_VERSION) \
+ http://ftp.postgresql.org/pub/source/v$(PKG_VERSION) \
+ ftp://ftp.postgresql.org/pub/source/v$(PKG_VERSION)
+
+PKG_HASH:=8455146ed9c69c93a57de954aead0302cafad035c2b242175d6aa1e17ebcb2fb
+
+PKG_BUILD_FLAGS:=no-mips16
+PKG_FIXUP:=autoreconf
+PKG_MACRO_PATHS:=config
+PKG_BUILD_DEPENDS:=postgresql/host
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/libpq
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=+libpthread
+ TITLE:=PostgreSQL client library
+ URL:=http://www.postgresql.org/
+ SUBMENU:=Database
+endef
+
+define Package/libpq/description
+PostgreSQL client library.
+endef
+
+define Package/pgsql-cli
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libncursesw +libpq +libreadline +librt +zlib
+ TITLE:=Command Line Interface (CLI) to PostgreSQL databases
+ URL:=http://www.postgresql.org/
+ SUBMENU:=Database
+endef
+
+define Package/pgsql-cli/description
+Command Line Interface (CLI) to PostgreSQL databases.
+endef
+
+define Package/pgsql-cli-extra
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libncursesw +libpq +libreadline +librt +zlib
+ TITLE:=Command Line extras for PostgreSQL databases
+ URL:=http://www.postgresql.org/
+ SUBMENU:=Database
+endef
+
+define Package/pgsql-cli-extra/description
+Command Line extras for PostgreSQL databases.
+endef
+
+define Package/pgsql-server
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+pgsql-cli +blockd
+ TITLE:=PostgreSQL databases Server
+ URL:=http://www.postgresql.org/
+ SUBMENU:=Database
+ USERID:=postgres=5432:postgres=5432
+endef
+
+define Package/pgsql-server/description
+PostgreSQL databases Server.
+endef
+
+PGSQL_SERVER_BIN := \
+ pg_amcheck \
+ pg_archivecleanup \
+ pg_basebackup \
+ pg_checksums \
+ pg_controldata \
+ pg_ctl \
+ pg_dump \
+ pg_dumpall \
+ pg_isready \
+ pg_recvlogical \
+ pg_receivewal \
+ pg_resetwal \
+ pg_restore \
+ pg_rewind \
+ pg_upgrade \
+ pg_verifybackup \
+ pg_waldump \
+ postgres \
+ initdb
+
+PGSQL_CLI_EXTRA_BIN := \
+ clusterdb \
+ createdb \
+ createuser \
+ dropdb \
+ dropuser \
+ oid2name \
+ pgbench \
+ reindexdb \
+ vacuumdb \
+ vacuumlo
+
+PGSQL_CONFIG_VARS:= \
+ pgac_cv_snprintf_long_long_int_format="%lld" \
+ pgac_cv_snprintf_size_t_support=yes \
+ USE_DEV_URANDOM=1 \
+ ac_cv_file__dev_urandom="/dev/urandom" \
+ ZIC=zic
+
+ifeq ($(CONFIG_USE_UCLIBC),y)
+# PostgreSQL does not build against uClibc with locales
+# enabled, due to an uClibc bug, see
+# http://lists.uclibc.org/pipermail/uclibc/2014-April/048326.html
+# so overwrite automatic detection and disable locale support
+PGSQL_CONFIG_VARS+= \
+ pgac_cv_type_locale_t=no
+endif
+
+TARGET_CONFIGURE_OPTS+=$(PGSQL_CONFIG_VARS)
+
+HOST_CONFIGURE_ARGS += \
+ --disable-nls \
+ --disable-rpath \
+ --without-bonjour \
+ --without-gssapi \
+ --without-ldap \
+ --without-openssl \
+ --without-pam \
+ --without-perl \
+ --without-python \
+ --without-readline \
+ --without-tcl \
+ --without-systemd \
+ --with-zlib="yes" \
+ --enable-depend
+
+CONFIGURE_ARGS += \
+ $(DISABLE_NLS) \
+ --disable-rpath \
+ --without-bonjour \
+ --without-gssapi \
+ --without-ldap \
+ --without-openssl \
+ --without-pam \
+ --without-perl \
+ --without-python \
+ --without-tcl \
+ --without-systemd \
+ --with-zlib="yes" \
+ --enable-depend \
+ $(if $(CONFIG_arc),--disable-spinlocks)
+
+HOST_CFLAGS += -std=gnu99
+
+# Need a native zic and pg_config for build
+define Host/Compile
+ +$(HOST_MAKE_VARS) MAKELEVEL=0 $(MAKE) -C $(HOST_BUILD_DIR)/src/bin/pg_config CC="$(HOSTCC)"
+ +$(HOST_MAKE_VARS) MAKELEVEL=0 $(MAKE) -C $(HOST_BUILD_DIR)/src/timezone CC="$(HOSTCC)"
+endef
+
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/lib/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/common/libpgcommon.a $(STAGING_DIR_HOSTPKG)/lib/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/port/libpgport.a $(STAGING_DIR_HOSTPKG)/lib/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/bin/pg_config/pg_config $(STAGING_DIR_HOSTPKG)/lib/
+ $(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin/
+ $(INSTALL_BIN) $(HOST_BUILD_DIR)/src/timezone/zic $(STAGING_DIR_HOSTPKG)/bin/
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) MAKELEVEL=0 all contrib
+endef
+
+# because PROFILE means something else in the project Makefile
+unexport PROFILE
+
+define Package/libpq/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpq.so.* $(1)/usr/lib/
+endef
+
+define Package/pgsql-cli/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/psql $(1)/usr/bin/
+endef
+
+define Package/pgsql-cli-extra/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(foreach bin,$(PGSQL_CLI_EXTRA_BIN),$(PKG_INSTALL_DIR)/usr/bin/$(bin)) $(1)/usr/bin/
+endef
+
+define Package/pgsql-server/conffiles
+/etc/config/postgresql
+endef
+
+define Package/pgsql-server/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(foreach bin,$(PGSQL_SERVER_BIN),$(PKG_INSTALL_DIR)/usr/bin/$(bin)) $(1)/usr/bin/
+
+ ln -sf postgres $(1)/usr/bin/postmaster
+
+ $(INSTALL_DIR) $(1)/usr/share/postgresql
+ $(CP) $(PKG_INSTALL_DIR)/usr/share/postgresql/* \
+ $(1)/usr/share/postgresql
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/postgresql \
+ $(1)/usr/lib/
+
+ $(INSTALL_DIR) $(1)/lib/functions
+ $(INSTALL_BIN) ./files/postgresql.sh $(1)/lib/functions/
+
+ $(INSTALL_DIR) $(1)/etc/config
+ $(INSTALL_DATA) ./files/postgresql.config $(1)/etc/config/postgresql
+
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/postgresql.init $(1)/etc/init.d/postgresql
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(CP) $(STAGING_DIR_HOSTPKG)/lib/pg_config $(1)/usr/bin
+ $(INSTALL_DIR) $(1)/host/bin/
+ $(LN) $(STAGING_DIR)/usr/bin/pg_config $(1)/host/bin
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libpq $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/libpq-fe.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config_manual.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/postgres_ext.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/pg_config_ext.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/postgresql $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libpq.{a,so*} $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libpq.pc $(1)/usr/lib/pkgconfig/
+endef
+
+$(eval $(call HostBuild))
+$(eval $(call BuildPackage,libpq))
+$(eval $(call BuildPackage,pgsql-cli))
+$(eval $(call BuildPackage,pgsql-cli-extra))
+$(eval $(call BuildPackage,pgsql-server))
diff --git a/external/subpack/libs/postgresql/files/postgresql.config b/external/subpack/libs/postgresql/files/postgresql.config
new file mode 100644
index 0000000..4760bf1
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.config
@@ -0,0 +1,2 @@
+config postgresql config
+ option PGDATA /var/postgresql/data
diff --git a/external/subpack/libs/postgresql/files/postgresql.init b/external/subpack/libs/postgresql/files/postgresql.init
new file mode 100644
index 0000000..5761336
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.init
@@ -0,0 +1,92 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2015 OpenWrt.org
+START=50
+
+PROG=/usr/bin/postmaster
+
+USE_PROCD=1
+
+fix_hosts() {
+ # make sure localhost (without a dot) is in /etc/hosts
+ grep -q 'localhost$' /etc/hosts || echo '127.0.0.1 localhost' >> /etc/hosts
+}
+
+fix_perms() {
+ # for whatever reason, /dev/null gets wrong perms
+ chmod a+w /dev/null
+}
+
+cleanup() {
+ if [ -f "$1/postmaster.pid" ]; then
+ rm "$1/postmaster.pid"
+ fi
+}
+
+start_service() {
+ . /lib/functions/postgresql.sh
+
+ config_load "postgresql"
+ config_get pgdata config PGDATA
+ config_get pgopts config PGOPTS
+
+ user_exists postgres 5432 || user_add postgres 5432
+ group_exists postgres 5432 || group_add postgres 5432
+
+ [ "$_BOOT" = "1" ] &&
+ [ "$(procd_get_mountpoints $pgdata)" ] && return 0
+
+ fix_perms
+ fix_hosts
+
+ if [ ! -e "${pgdata}/PG_VERSION" ]; then
+ pg_init_data ${pgdata}
+ [ $? -gt 0 ] && return 1
+ fi
+
+ cleanup "${pgdata}"
+
+ mkdir -m 0755 -p /var/run/postgresql
+ chmod 0750 /var/run/postgresql
+ chown postgres:postgres /var/run/postgresql
+ procd_open_instance postmaster
+ procd_set_param user postgres
+ procd_set_param command $PROG
+ procd_append_param command -D "${pgdata}"
+ procd_append_param command -k "/var/run/postgresql"
+ [ -n "${pgopts}" ] && procd_append_param command -o "${pgopts}"
+ procd_set_param respawn retry=60
+ procd_add_jail postgresql log
+ procd_add_jail_mount /usr/lib/postgresql /usr/share/postgresql
+ procd_add_jail_mount_rw /var/run/postgresql "${pgdata}"
+ procd_add_jail_mount_rw /dev/shm
+ procd_set_param stderr 1
+ procd_set_param stdout 1
+ procd_close_instance
+
+ procd_open_instance uci_dbinit
+ procd_set_param user postgres
+ procd_set_param command /lib/functions/postgresql.sh init "${pgdata}"
+ procd_set_param stdout 1
+ procd_set_param stderr 1
+ procd_close_instance
+}
+
+boot() {
+ _BOOT=1 start
+}
+
+service_triggers() {
+ config_load "postgresql"
+ config_get pgdata config PGDATA
+ procd_add_restart_mount_trigger "${pgdata}"
+}
+
+stop_service() {
+ procd_send_signal "postgresql" postmaster SIGTERM
+}
+
+status_service() {
+ config_load "postgresql"
+ config_get pgdata config PGDATA
+ /usr/bin/pg_ctl status -U postgres -D "${pgdata}"
+}
diff --git a/external/subpack/libs/postgresql/files/postgresql.sh b/external/subpack/libs/postgresql/files/postgresql.sh
new file mode 100644
index 0000000..e1076d5
--- /dev/null
+++ b/external/subpack/libs/postgresql/files/postgresql.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+PSQL="/usr/bin/psql"
+
+free_megs() {
+ fsdir=$1
+ while [ ! -d "$fsdir" ]; do
+ fsdir="$(dirname "$fsdir")"
+ done
+ df -m $fsdir | while read fs bl us av cap mnt; do [ "$av" = "Available" ] || echo $av; done
+}
+
+pg_init_data() {
+ # make sure we got at least 50MB of free space
+ [ $(free_megs "$1") -lt 50 ] && return 1
+ pg_ctl initdb -U postgres -D "$1"
+}
+
+pg_server_ready() {
+ t=0
+ while [ $t -le 90 ]; do
+ psql -h /var/run/postgresql/ -U postgres -c "\q" 1>/dev/null 2>/dev/null && return 0
+ t=$((t+1))
+ sleep 1
+ done
+ return 1
+}
+
+
+pg_test_db() {
+ echo "SELECT datname FROM pg_catalog.pg_database WHERE datname = '$1';" |
+ $PSQL -h /var/run/postgresql -w -U "postgres" -d "template1" -q |
+ grep -q "0 rows" && return 1
+
+ return 0
+}
+
+pg_include_sql() {
+ if [ "$3" ]; then
+ env PGPASSWORD="$3" $PSQL -h /var/run/postgresql -U "$2" -d "$1" -e -f "$4"
+ return $?
+ else
+ $PSQL -w -h /var/run/postgresql -U "$2" -d "$1" -e -f "$4"
+ return $?
+ fi
+}
+
+# $1: dbname, $2: username, $3: password, $4: sql populate script
+pg_require_db() {
+ local ret
+ local dbname="$1"
+ local dbuser="$2"
+ local dbpass="$3"
+ local exuser
+
+ pg_test_db $@ && return 0
+
+ shift ; shift ; shift
+
+ echo "CREATE DATABASE $dbname;" |
+ $PSQL -h /var/run/postgresql -U postgres -d template1 -e || return $?
+
+ if [ "$dbuser" ]; then
+ echo "SELECT usename FROM pg_catalog.pg_user WHERE usename = '$dbuser';" |
+ $PSQL -h /var/run/postgresql -U postgres -d template1 -e | grep -q "0 rows" &&
+ ( echo -n "CREATE USER $dbuser"
+ [ "$dbpass" ] && echo -n " WITH PASSWORD '$dbpass'"
+ echo " NOCREATEDB NOSUPERUSER NOCREATEROLE NOINHERIT;" ) |
+ $PSQL -h /var/run/postgresql -U postgres -d template1 -e
+
+ echo "GRANT ALL PRIVILEGES ON DATABASE \"$dbname\" TO $dbuser;" |
+ $PSQL -h /var/run/postgresql -U postgres -d template1 -e
+ fi
+
+ while [ "$1" ]; do
+ pg_include_sql "$dbname" "$dbuser" "$dbpass" "$1"
+ ret=$?
+ [ $ret != 0 ] && break
+ shift
+ done
+
+ return $ret
+}
+
+uci_require_db() {
+ local dbname dbuser dbpass dbscript
+ config_get dbname $1 name
+ config_get dbuser $1 user
+ config_get dbpass $1 pass
+ config_get dbscript $1 script
+ pg_require_db "$dbname" "$dbuser" "$dbpass" $dbscript
+}
+
+[ "$1" = "init" ] && {
+ . /lib/functions.sh
+ pg_server_ready $2 || exit 1
+ config_load postgresql
+ config_foreach uci_require_db postgres-db
+}
diff --git a/external/subpack/libs/postgresql/patches/050-build-contrib.patch b/external/subpack/libs/postgresql/patches/050-build-contrib.patch
new file mode 100644
index 0000000..88a23f0
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/050-build-contrib.patch
@@ -0,0 +1,11 @@
+--- a/GNUmakefile.in
++++ b/GNUmakefile.in
+@@ -8,7 +8,7 @@ subdir =
+ top_builddir = .
+ include $(top_builddir)/src/Makefile.global
+
+-$(call recurse,all install,src config)
++$(call recurse,all install,src config contrib)
+
+ docs:
+ $(MAKE) -C doc all
diff --git a/external/subpack/libs/postgresql/patches/200-ranlib.patch b/external/subpack/libs/postgresql/patches/200-ranlib.patch
new file mode 100644
index 0000000..d4184a3
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/200-ranlib.patch
@@ -0,0 +1,10 @@
+--- a/src/port/Makefile
++++ b/src/port/Makefile
+@@ -83,6 +83,7 @@ uninstall:
+ libpgport.a: $(OBJS)
+ rm -f $@
+ $(AR) $(AROPT) $@ $^
++ $(RANLIB) libpgport.a
+
+ # getaddrinfo.o and getaddrinfo_shlib.o need PTHREAD_CFLAGS (but getaddrinfo_srv.o does not)
+ getaddrinfo.o: CFLAGS+=$(PTHREAD_CFLAGS)
diff --git a/external/subpack/libs/postgresql/patches/300-fix-includes.patch b/external/subpack/libs/postgresql/patches/300-fix-includes.patch
new file mode 100644
index 0000000..3611c8e
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/300-fix-includes.patch
@@ -0,0 +1,14 @@
+--- a/src/bin/pg_ctl/pg_ctl.c
++++ b/src/bin/pg_ctl/pg_ctl.c
+@@ -12,9 +12,11 @@
+ #include "postgres_fe.h"
+
+ #include <fcntl.h>
++#include <pwd.h>
+ #include <signal.h>
+ #include <time.h>
+ #include <sys/stat.h>
++#include <sys/types.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+
diff --git a/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch b/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch
new file mode 100644
index 0000000..33637f5
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/700-no-arm-crc-march-change.patch
@@ -0,0 +1,15 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -2239,9 +2239,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
+ # flags. If not, check if adding -march=armv8-a+crc flag helps.
+ # CFLAGS_ARMV8_CRC32C is set if the extra flag is required.
+ PGAC_ARMV8_CRC32C_INTRINSICS([])
+-if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
+- PGAC_ARMV8_CRC32C_INTRINSICS([-march=armv8-a+crc])
+-fi
++#if test x"$pgac_armv8_crc32c_intrinsics" != x"yes"; then
++# PGAC_ARMV8_CRC32C_INTRINSICS([-march=armv8-a+crc])
++#fi
+ AC_SUBST(CFLAGS_ARMV8_CRC32C)
+
+ # Select CRC-32C implementation.
diff --git a/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch b/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch
new file mode 100644
index 0000000..b1222cb
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/800-busybox-default-pager.patch
@@ -0,0 +1,14 @@
+--- a/src/include/fe_utils/print.h
++++ b/src/include/fe_utils/print.h
+@@ -19,11 +19,7 @@
+
+
+ /* This is not a particularly great place for this ... */
+-#ifndef __CYGWIN__
+-#define DEFAULT_PAGER "more"
+-#else
+ #define DEFAULT_PAGER "less"
+-#endif
+
+ enum printFormat
+ {
diff --git a/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch b/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch
new file mode 100644
index 0000000..64d558f
--- /dev/null
+++ b/external/subpack/libs/postgresql/patches/900-pg_ctl-setuid.patch
@@ -0,0 +1,107 @@
+--- a/src/bin/pg_ctl/pg_ctl.c
++++ b/src/bin/pg_ctl/pg_ctl.c
+@@ -96,6 +96,7 @@ static char *event_source = NULL;
+ static char *register_servicename = "PostgreSQL"; /* FIXME: + version ID? */
+ static char *register_username = NULL;
+ static char *register_password = NULL;
++static char *username = "";
+ static char *argv0 = NULL;
+ static bool allow_core_files = false;
+ static time_t start_time;
+@@ -2086,6 +2087,9 @@ do_help(void)
+ #endif
+ printf(_(" -s, --silent only print errors, no informational messages\n"));
+ printf(_(" -t, --timeout=SECS seconds to wait when using -w option\n"));
++#if !defined(WIN32) && !defined(__CYGWIN__)
++ printf(_(" -U, --username=NAME user name of account PostgreSQL server is running as\n"));
++#endif
+ printf(_(" -V, --version output version information, then exit\n"));
+ printf(_(" -w, --wait wait until operation completes (default)\n"));
+ printf(_(" -W, --no-wait do not wait until operation completes\n"));
+@@ -2298,6 +2302,7 @@ main(int argc, char **argv)
+ {"options", required_argument, NULL, 'o'},
+ {"silent", no_argument, NULL, 's'},
+ {"timeout", required_argument, NULL, 't'},
++ {"username", required_argument, NULL, 'U'},
+ {"core-files", no_argument, NULL, 'c'},
+ {"wait", no_argument, NULL, 'w'},
+ {"no-wait", no_argument, NULL, 'W'},
+@@ -2338,20 +2343,6 @@ main(int argc, char **argv)
+ }
+ }
+
+- /*
+- * Disallow running as root, to forestall any possible security holes.
+- */
+-#ifndef WIN32
+- if (geteuid() == 0)
+- {
+- write_stderr(_("%s: cannot be run as root\n"
+- "Please log in (using, e.g., \"su\") as the "
+- "(unprivileged) user that will\n"
+- "own the server process.\n"),
+- progname);
+- exit(1);
+- }
+-#endif
+
+ env_wait = getenv("PGCTLTIMEOUT");
+ if (env_wait != NULL)
+@@ -2437,11 +2428,15 @@ main(int argc, char **argv)
+ wait_seconds_arg = true;
+ break;
+ case 'U':
++#if defined(WIN32) || defined(__CYGWIN__)
+ if (strchr(optarg, '\\'))
+ register_username = pg_strdup(optarg);
+ else
+ /* Prepend .\ for local accounts */
+ register_username = psprintf(".\\%s", optarg);
++#else
++ username = pg_strdup(optarg);
++#endif
+ break;
+ case 'w':
+ do_wait = true;
+@@ -2523,6 +2518,41 @@ main(int argc, char **argv)
+ exit(1);
+ }
+
++ /*
++ * Disallow running as root, to forestall any possible security holes.
++ */
++#if !defined(WIN32) && !defined(__CYGWIN__)
++ if (geteuid() == 0)
++ {
++ struct passwd *p;
++ if (!username || !strlen(username)) {
++ fprintf(stderr,
++ _("%s: when run as root, username needs to be provided\n"),
++ progname);
++ exit(1);
++ }
++ p = getpwnam(username);
++ if (!p) {
++ fprintf(stderr,
++ _("%s: invalid username: %s\n"),
++ progname, username);
++ exit(1);
++ }
++ if (!p->pw_uid) {
++ fprintf(stderr,
++ _("%s: user needs to be non-root\n"),
++ progname);
++ exit(1);
++ }
++ if (setgid(p->pw_gid) || setuid(p->pw_uid)) {
++ fprintf(stderr,
++ _("%s: failed to set user id %d: %d (%s)\n"),
++ progname, p->pw_uid, errno, strerror(errno));
++ exit(1);
++ }
++ }
++#endif
++
+ /* Note we put any -D switch into the env var above */
+ pg_config = getenv("PGDATA");
+ if (pg_config)