Index: backend/bootstrap/bootstrap.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.184
diff -c -c -r1.184 bootstrap.c
*** backend/bootstrap/bootstrap.c	6 Jun 2004 00:41:26 -0000	1.184
--- backend/bootstrap/bootstrap.c	14 Jun 2004 19:20:38 -0000
***************
*** 328,334 ****
  	{
  		if (!potential_DataDir)
  		{
! 			fprintf(stderr,
  					gettext("%s does not know where to find the database system data.\n"
  							"You must specify the directory that contains the database system\n"
  							"either by specifying the -D invocation option or by setting the\n"
--- 328,334 ----
  	{
  		if (!potential_DataDir)
  		{
! 			write_stderr(
  					gettext("%s does not know where to find the database system data.\n"
  							"You must specify the directory that contains the database system\n"
  							"either by specifying the -D invocation option or by setting the\n"
***************
*** 503,509 ****
  static void
  usage(void)
  {
! 	fprintf(stderr,
  			gettext("Usage:\n"
  					"  postgres -boot [OPTION]... DBNAME\n"
  					"  -c NAME=VALUE    set run-time parameter\n"
--- 503,509 ----
  static void
  usage(void)
  {
! 	write_stderr(
  			gettext("Usage:\n"
  					"  postgres -boot [OPTION]... DBNAME\n"
  					"  -c NAME=VALUE    set run-time parameter\n"
Index: backend/main/main.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/main/main.c,v
retrieving revision 1.86
diff -c -c -r1.86 main.c
*** backend/main/main.c	3 Jun 2004 00:07:36 -0000	1.86
--- backend/main/main.c	14 Jun 2004 19:36:23 -0000
***************
*** 41,46 ****
--- 41,47 ----
  #include "tcop/tcopprot.h"
  #include "utils/help_config.h"
  #include "utils/ps_status.h"
+ #include "utils/elog.h"
  #ifdef WIN32
  #include "libpq/pqsignal.h"
  #endif
***************
*** 91,97 ****
  #if defined(__alpha)			/* no __alpha__ ? */
  	if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
  				   (unsigned long) NULL) < 0)
! 		fprintf(stderr, gettext("%s: setsysinfo failed: %s\n"),
  				argv[0], strerror(errno));
  #endif
  #endif   /* NOFIXADE || NOPRINTADE */
--- 92,98 ----
  #if defined(__alpha)			/* no __alpha__ ? */
  	if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
  				   (unsigned long) NULL) < 0)
! 		write_stderr(gettext("%s: setsysinfo failed: %s\n"),
  				argv[0], strerror(errno));
  #endif
  #endif   /* NOFIXADE || NOPRINTADE */
***************
*** 109,115 ****
  		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
  		if (err != 0)
  		{
! 			fprintf(stderr, "%s: WSAStartup failed: %d\n",
  					argv[0], err);
  			exit(1);
  		}
--- 110,116 ----
  		err = WSAStartup(MAKEWORD(2, 2), &wsaData);
  		if (err != 0)
  		{
! 			write_stderr("%s: WSAStartup failed: %d\n",
  					argv[0], err);
  			exit(1);
  		}
***************
*** 212,218 ****
  		 */
  		if (geteuid() == 0)
  		{
! 			fprintf(stderr,
  					gettext("\"root\" execution of the PostgreSQL server is not permitted.\n"
  							"The server must be started under an unprivileged user ID to prevent\n"
  							"possible system security compromise.  See the documentation for\n"
--- 213,219 ----
  		 */
  		if (geteuid() == 0)
  		{
! 			write_stderr(
  					gettext("\"root\" execution of the PostgreSQL server is not permitted.\n"
  							"The server must be started under an unprivileged user ID to prevent\n"
  							"possible system security compromise.  See the documentation for\n"
***************
*** 233,243 ****
  		 */
  		if (getuid() != geteuid())
  		{
! 			fprintf(stderr,
  				 gettext("%s: real and effective user IDs must match\n"),
  					argv[0]);
  			exit(1);
  		}
  #endif   /* !WIN32 */
  	}

--- 234,254 ----
  		 */
  		if (getuid() != geteuid())
  		{
! 			write_stderr(
  				 gettext("%s: real and effective user IDs must match\n"),
  					argv[0]);
  			exit(1);
  		}
+ #else /* !WIN32 */
+ 		if (pgwin32_is_admin()) {
+ 			write_stderr(
+ 				   gettext("execution of PostgreSQL by a user with administrative permissions is not permitted.\n"
+ 							"The server must be started under an unprivileged user ID to prevent\n"
+ 							"possible system security compromise.  See the documentation for\n"
+ 				"more information on how to properly start the server.\n"
+ 							));
+ 			exit(1);
+ 		}
  #endif   /* !WIN32 */
  	}

***************
*** 292,298 ****
  	pw = getpwuid(geteuid());
  	if (pw == NULL)
  	{
! 		fprintf(stderr, gettext("%s: invalid effective UID: %d\n"),
  				argv[0], (int) geteuid());
  		exit(1);
  	}
--- 303,309 ----
  	pw = getpwuid(geteuid());
  	if (pw == NULL)
  	{
! 		write_stderr(gettext("%s: invalid effective UID: %d\n"),
  				argv[0], (int) geteuid());
  		exit(1);
  	}
***************
*** 305,311 ****
  		pw_name_persist = malloc(namesize);
  		if (!GetUserName(pw_name_persist, &namesize))
  		{
! 			fprintf(stderr, gettext("%s: could not determine user name (GetUserName failed)\n"),
  					argv[0]);
  			exit(1);
  		}
--- 316,322 ----
  		pw_name_persist = malloc(namesize);
  		if (!GetUserName(pw_name_persist, &namesize))
  		{
! 			write_stderr(gettext("%s: could not determine user name (GetUserName failed)\n"),
  					argv[0]);
  			exit(1);
  		}
Index: backend/port/win32/Makefile
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/port/win32/Makefile,v
retrieving revision 1.4
diff -c -c -r1.4 Makefile
*** backend/port/win32/Makefile	12 Apr 2004 16:19:18 -0000	1.4
--- backend/port/win32/Makefile	14 Jun 2004 18:34:51 -0000
***************
*** 12,18 ****
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global

! OBJS = sema.o shmem.o timer.o socket.o signal.o

  all: SUBSYS.o

--- 12,18 ----
  top_builddir = ../../../..
  include $(top_builddir)/src/Makefile.global

! OBJS = sema.o shmem.o timer.o socket.o signal.o security.o

  all: SUBSYS.o

Index: backend/port/win32/signal.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/port/win32/signal.c,v
retrieving revision 1.3
diff -c -c -r1.3 signal.c
*** backend/port/win32/signal.c	27 May 2004 14:39:29 -0000	1.3
--- backend/port/win32/signal.c	14 Jun 2004 19:20:21 -0000
***************
*** 221,227 ****
  						   PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
  		if (pipe == INVALID_HANDLE_VALUE)
  		{
! 			fprintf(stderr, gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError());
  			SleepEx(500, FALSE);
  			continue;
  		}
--- 221,227 ----
  						   PIPE_UNLIMITED_INSTANCES, 16, 16, 1000, NULL);
  		if (pipe == INVALID_HANDLE_VALUE)
  		{
! 			write_stderr(gettext("Failed to create signal listener pipe: %i. Retrying.\n"), (int) GetLastError());
  			SleepEx(500, FALSE);
  			continue;
  		}
***************
*** 233,239 ****
  					  (LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread,
  								   (LPVOID) pipe, 0, NULL);
  			if (hThread == INVALID_HANDLE_VALUE)
! 				fprintf(stderr, gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError());
  			else
  				CloseHandle(hThread);
  		}
--- 233,239 ----
  					  (LPTHREAD_START_ROUTINE) pg_signal_dispatch_thread,
  								   (LPVOID) pipe, 0, NULL);
  			if (hThread == INVALID_HANDLE_VALUE)
! 				write_stderr(gettext("Failed to create signal dispatch thread: %i\n"), (int) GetLastError());
  			else
  				CloseHandle(hThread);
  		}
Index: backend/postmaster/postmaster.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.404
diff -c -c -r1.404 postmaster.c
*** backend/postmaster/postmaster.c	14 Jun 2004 18:08:19 -0000	1.404
--- backend/postmaster/postmaster.c	14 Jun 2004 19:32:39 -0000
***************
*** 380,386 ****
  #ifdef USE_ASSERT_CHECKING
  				SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
  #else
! 				postmaster_error("assert checking is not compiled in");
  #endif
  				break;
  			case 'a':
--- 380,386 ----
  #ifdef USE_ASSERT_CHECKING
  				SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
  #else
! 				write_stderr("%s: assert checking is not compiled in\n", progname);
  #endif
  				break;
  			case 'a':
***************
*** 503,509 ****
  				}

  			default:
! 				fprintf(stderr,
  					gettext("Try \"%s --help\" for more information.\n"),
  						progname);
  				ExitPostmaster(1);
--- 503,509 ----
  				}

  			default:
! 				write_stderr(
  					gettext("Try \"%s --help\" for more information.\n"),
  						progname);
  				ExitPostmaster(1);
***************
*** 515,522 ****
  	 */
  	if (optind < argc)
  	{
! 		postmaster_error("invalid argument: \"%s\"", argv[optind]);
! 		fprintf(stderr,
  				gettext("Try \"%s --help\" for more information.\n"),
  				progname);
  		ExitPostmaster(1);
--- 515,522 ----
  	 */
  	if (optind < argc)
  	{
! 		write_stderr("%s: invalid argument: \"%s\"\n", progname, argv[optind]);
! 		write_stderr(
  				gettext("Try \"%s --help\" for more information.\n"),
  				progname);
  		ExitPostmaster(1);
***************
*** 547,559 ****
  		 * for lack of buffers.  The specific choices here are somewhat
  		 * arbitrary.
  		 */
! 		postmaster_error("the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16");
  		ExitPostmaster(1);
  	}

  	if (ReservedBackends >= MaxBackends)
  	{
! 		postmaster_error("superuser_reserved_connections must be less than max_connections");
  		ExitPostmaster(1);
  	}

--- 547,559 ----
  		 * for lack of buffers.  The specific choices here are somewhat
  		 * arbitrary.
  		 */
! 		write_stderr("%s: the number of buffers (-B) must be at least twice the number of allowed connections (-N) and at least 16\n", progname);
  		ExitPostmaster(1);
  	}

  	if (ReservedBackends >= MaxBackends)
  	{
! 		write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
  		ExitPostmaster(1);
  	}

***************
*** 562,568 ****
  	 */
  	if (!CheckDateTokenTables())
  	{
! 		postmaster_error("invalid datetoken tables, please fix");
  		ExitPostmaster(1);
  	}

--- 562,568 ----
  	 */
  	if (!CheckDateTokenTables())
  	{
! 		write_stderr("%s: invalid datetoken tables, please fix\n", progname);
  		ExitPostmaster(1);
  	}

***************
*** 858,864 ****

  	if (checkdir == NULL)
  	{
! 		fprintf(stderr,
  				gettext("%s does not know where to find the database system data.\n"
  						"You must specify the directory that contains the database system\n"
  						"either by specifying the -D invocation option or by setting the\n"
--- 858,864 ----

  	if (checkdir == NULL)
  	{
! 		write_stderr(
  				gettext("%s does not know where to find the database system data.\n"
  						"You must specify the directory that contains the database system\n"
  						"either by specifying the -D invocation option or by setting the\n"
***************
*** 905,911 ****
  	fp = AllocateFile(path, PG_BINARY_R);
  	if (fp == NULL)
  	{
! 		fprintf(stderr,
  				gettext("%s: could not find the database system\n"
  						"Expected to find it in the directory \"%s\",\n"
  						"but could not open file \"%s\": %s\n"),
--- 905,911 ----
  	fp = AllocateFile(path, PG_BINARY_R);
  	if (fp == NULL)
  	{
! 		write_stderr(
  				gettext("%s: could not find the database system\n"
  						"Expected to find it in the directory \"%s\",\n"
  						"but could not open file \"%s\": %s\n"),
***************
*** 952,959 ****
  	pid = fork();
  	if (pid == (pid_t) -1)
  	{
! 		postmaster_error("could not fork background process: %s",
! 						 strerror(errno));
  		ExitPostmaster(1);
  	}
  	else if (pid)
--- 952,959 ----
  	pid = fork();
  	if (pid == (pid_t) -1)
  	{
! 		write_stderr("%s: could not fork background process: %s\n",
! 					 progname, strerror(errno));
  		ExitPostmaster(1);
  	}
  	else if (pid)
***************
*** 974,981 ****
  #ifdef HAVE_SETSID
  	if (setsid() < 0)
  	{
! 		postmaster_error("could not dissociate from controlling TTY: %s",
! 						 strerror(errno));
  		ExitPostmaster(1);
  	}
  #endif
--- 974,981 ----
  #ifdef HAVE_SETSID
  	if (setsid() < 0)
  	{
! 		write_stderr("%s: could not dissociate from controlling TTY: %s\n",
! 					 progname, strerror(errno));
  		ExitPostmaster(1);
  	}
  #endif
***************
*** 3152,3176 ****
  	return true;
  }

- /*
-  * This should be used only for reporting "interactive" errors (essentially,
-  * bogus arguments on the command line).  Once the postmaster is launched,
-  * use ereport.  In particular, don't use this for anything that occurs
-  * after pmdaemonize.
-  */
- static void
- postmaster_error(const char *fmt,...)
- {
- 	va_list		ap;
-
- 	fprintf(stderr, "%s: ", progname);
- 	va_start(ap, fmt);
- 	vfprintf(stderr, gettext(fmt), ap);
- 	va_end(ap);
- 	fprintf(stderr, "\n");
- }
- 
- 
  #ifdef EXEC_BACKEND
  
  /*
--- 3152,3157 ----
***************
*** 3609,3615 ****
  	if (r == WAIT_OBJECT_0)
  		pg_queue_signal(SIGCHLD);
  	else
! 		fprintf(stderr, "ERROR: failed to wait on child process handle: %d\n",
  				(int) GetLastError());
  	CloseHandle(procHandle);
  	return 0;
--- 3590,3596 ----
  	if (r == WAIT_OBJECT_0)
  		pg_queue_signal(SIGCHLD);
  	else
! 		write_stderr("ERROR: failed to wait on child process handle: %d\n",
  				(int) GetLastError());
  	CloseHandle(procHandle);
  	return 0;
Index: backend/tcop/postgres.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.420
diff -c -c -r1.420 postgres.c
*** backend/tcop/postgres.c	11 Jun 2004 01:09:00 -0000	1.420
--- backend/tcop/postgres.c	14 Jun 2004 19:20:04 -0000
***************
*** 2578,2584 ****
  	{
  		if (!potential_DataDir)
  		{
! 			fprintf(stderr,
  					gettext("%s does not know where to find the database system data.\n"
  							"You must specify the directory that contains the database system\n"
  							"either by specifying the -D invocation option or by setting the\n"
--- 2578,2584 ----
  	{
  		if (!potential_DataDir)
  		{
! 			write_stderr(
  					gettext("%s does not know where to find the database system data.\n"
  							"You must specify the directory that contains the database system\n"
  							"either by specifying the -D invocation option or by setting the\n"
Index: backend/utils/error/assert.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/assert.c,v
retrieving revision 1.26
diff -c -c -r1.26 assert.c
*** backend/utils/error/assert.c	19 Apr 2004 17:42:58 -0000	1.26
--- backend/utils/error/assert.c	14 Jun 2004 19:19:56 -0000
***************
*** 31,40 ****
  	if (!PointerIsValid(conditionName)
  		|| !PointerIsValid(fileName)
  		|| !PointerIsValid(errorType))
! 		fprintf(stderr, "TRAP: ExceptionalCondition: bad arguments\n");
  	else
  	{
! 		fprintf(stderr, "TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
  				errorType, conditionName,
  				fileName, lineNumber);
  	}
--- 31,40 ----
  	if (!PointerIsValid(conditionName)
  		|| !PointerIsValid(fileName)
  		|| !PointerIsValid(errorType))
! 		write_stderr("TRAP: ExceptionalCondition: bad arguments\n");
  	else
  	{
! 		write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
  				errorType, conditionName,
  				fileName, lineNumber);
  	}
Index: backend/utils/error/elog.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/error/elog.c,v
retrieving revision 1.140
diff -c -c -r1.140 elog.c
*** backend/utils/error/elog.c	3 Jun 2004 02:08:04 -0000	1.140
--- backend/utils/error/elog.c	14 Jun 2004 19:22:10 -0000
***************
*** 1755,1757 ****
--- 1755,1790 ----
  			appendStringInfoCharMacro(buf, '\t');
  	}
  }
+ 
+ 
+ 
+ /* 
+  * Write errors to stderr (or by equal means when stderr is
+  * not available). Used before ereport/elog can be used
+  * safely (memory context, GUC load etc) 
+  */
+ extern void
+ write_stderr(const char *fmt,...)
+ {
+ 	va_list ap;
+ 
+ 	va_start(ap, fmt);
+ #ifndef WIN32
+ 	/* On Unix, we just fprintf to stderr */
+ 	vfprintf(stderr, fmt, ap);
+ #else
+ 	/* On Win32, we print to stderr if running on a console, or write to 
+ 	 * eventlog if running as a service */
+ 	if (/* FIXME: Running as service? */ 0) 
+ 	{
+ 		char errbuf[2048]; /* Arbitrary size? */
+ 
+ 		vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
+ 		
+ 		write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
+ 	}
+ 	else /* Not running as service, write to stderr */
+ 		vfprintf(stderr, fmt, ap);
+ #endif
+ 	va_end(ap);
+ }
Index: backend/utils/misc/help_config.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/misc/help_config.c,v
retrieving revision 1.11
diff -c -c -r1.11 help_config.c
*** backend/utils/misc/help_config.c	2 Jun 2004 18:09:32 -0000	1.11
--- backend/utils/misc/help_config.c	14 Jun 2004 19:22:22 -0000
***************
*** 122,128 ****
  			break;
  
  		default:
! 			fprintf(stderr, "internal error: unrecognized run-time parameter type\n");
  			break;
  	}
  
--- 122,128 ----
  			break;
  
  		default:
! 			write_stderr("internal error: unrecognized run-time parameter type\n");
  			break;
  	}
  
Index: include/port/win32.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/port/win32.h,v
retrieving revision 1.25
diff -c -c -r1.25 win32.h
*** include/port/win32.h	27 May 2004 14:39:33 -0000	1.25
--- include/port/win32.h	14 Jun 2004 19:00:15 -0000
***************
*** 140,145 ****
--- 140,147 ----
  const char *pgwin32_socket_strerror(int err);
  #endif
  
+ /* in backend/port/win32/security.c */
+ extern int pgwin32_is_admin(void);
  
  /* Some extra signals */
  #define SIGHUP				1
Index: include/utils/elog.h
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/include/utils/elog.h,v
retrieving revision 1.68
diff -c -c -r1.68 elog.h
*** include/utils/elog.h	5 Apr 2004 03:02:10 -0000	1.68
--- include/utils/elog.h	14 Jun 2004 19:21:41 -0000
***************
*** 164,169 ****
--- 164,180 ----
  
  extern DLLIMPORT ErrorContextCallback *error_context_stack;
  
+ /* 
+  * Write errors to stderr (or by equal means when stderr is
+  * not available). Used before ereport/elog can be used
+  * safely (memory context, GUC load etc)
+  */
+ extern void
+ write_stderr(const char *fmt,...)
+ /* This extension allows gcc to check the format string for consistency with
+    the supplied arguments. */
+ __attribute__((format(printf, 1, 2)));
+

  /* GUC-configurable parameters */


