00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "postgres.h"
00022
00023 #include <pwd.h>
00024 #include <unistd.h>
00025
00026 #if defined(__alpha) && defined(__osf__)
00027 #include <sys/sysinfo.h>
00028 #include "machine/hal_sysinfo.h"
00029 #define ASSEMBLER
00030 #include <sys/proc.h>
00031 #undef ASSEMBLER
00032 #endif
00033
00034 #if defined(__NetBSD__)
00035 #include <sys/param.h>
00036 #endif
00037
00038 #include "bootstrap/bootstrap.h"
00039 #include "postmaster/postmaster.h"
00040 #include "tcop/tcopprot.h"
00041 #include "utils/help_config.h"
00042 #include "utils/pg_locale.h"
00043 #include "utils/ps_status.h"
00044
00045
00046 const char *progname;
00047
00048
00049 static void startup_hacks(const char *progname);
00050 static void help(const char *progname);
00051 static void check_root(const char *progname);
00052 static char *get_current_username(const char *progname);
00053
00054
00055
00056
00057
00058 int
00059 main(int argc, char *argv[])
00060 {
00061 progname = get_progname(argv[0]);
00062
00063
00064
00065
00066 startup_hacks(progname);
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 argv = save_ps_display_args(argc, argv);
00080
00081
00082
00083
00084
00085 #if defined(WIN32) && defined(HAVE_MINIDUMP_TYPE)
00086 pgwin32_install_crashdump_handler();
00087 #endif
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098 set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));
00099
00100 #ifdef WIN32
00101
00102
00103
00104
00105
00106
00107
00108 {
00109 char *env_locale;
00110
00111 if ((env_locale = getenv("LC_COLLATE")) != NULL)
00112 pg_perm_setlocale(LC_COLLATE, env_locale);
00113 else
00114 pg_perm_setlocale(LC_COLLATE, "");
00115
00116 if ((env_locale = getenv("LC_CTYPE")) != NULL)
00117 pg_perm_setlocale(LC_CTYPE, env_locale);
00118 else
00119 pg_perm_setlocale(LC_CTYPE, "");
00120 }
00121 #else
00122 pg_perm_setlocale(LC_COLLATE, "");
00123 pg_perm_setlocale(LC_CTYPE, "");
00124 #endif
00125
00126 #ifdef LC_MESSAGES
00127 pg_perm_setlocale(LC_MESSAGES, "");
00128 #endif
00129
00130
00131
00132
00133
00134 pg_perm_setlocale(LC_MONETARY, "C");
00135 pg_perm_setlocale(LC_NUMERIC, "C");
00136 pg_perm_setlocale(LC_TIME, "C");
00137
00138
00139
00140
00141
00142
00143 unsetenv("LC_ALL");
00144
00145
00146
00147
00148 if (argc > 1)
00149 {
00150 if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
00151 {
00152 help(progname);
00153 exit(0);
00154 }
00155 if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
00156 {
00157 puts("postgres (PostgreSQL) " PG_VERSION);
00158 exit(0);
00159 }
00160 }
00161
00162
00163
00164
00165 check_root(progname);
00166
00167
00168
00169
00170
00171 #ifdef EXEC_BACKEND
00172 if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)
00173 SubPostmasterMain(argc, argv);
00174 #endif
00175
00176 #ifdef WIN32
00177
00178
00179
00180
00181
00182
00183
00184 pgwin32_signal_initialize();
00185 #endif
00186
00187 if (argc > 1 && strcmp(argv[1], "--boot") == 0)
00188 AuxiliaryProcessMain(argc, argv);
00189 else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
00190 GucInfoMain();
00191 else if (argc > 1 && strcmp(argv[1], "--single") == 0)
00192 PostgresMain(argc, argv,
00193 NULL,
00194 get_current_username(progname));
00195 else
00196 PostmasterMain(argc, argv);
00197 abort();
00198 }
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213 static void
00214 startup_hacks(const char *progname)
00215 {
00216
00217
00218
00219
00220
00221
00222
00223 #ifdef NOFIXADE
00224
00225 #if defined(__alpha)
00226 {
00227 int buffer[] = {SSIN_UACPROC, UAC_SIGBUS | UAC_NOPRINT};
00228
00229 if (setsysinfo(SSI_NVPAIRS, buffer, 1, (caddr_t) NULL,
00230 (unsigned long) NULL) < 0)
00231 write_stderr("%s: setsysinfo failed: %s\n",
00232 progname, strerror(errno));
00233 }
00234 #endif
00235 #endif
00236
00237
00238
00239
00240 #ifdef WIN32
00241 {
00242 WSADATA wsaData;
00243 int err;
00244
00245
00246 setvbuf(stdout, NULL, _IONBF, 0);
00247 setvbuf(stderr, NULL, _IONBF, 0);
00248
00249
00250 err = WSAStartup(MAKEWORD(2, 2), &wsaData);
00251 if (err != 0)
00252 {
00253 write_stderr("%s: WSAStartup failed: %d\n",
00254 progname, err);
00255 exit(1);
00256 }
00257
00258
00259 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
00260 }
00261 #endif
00262 }
00263
00264
00265
00266
00267
00268
00269 static void
00270 help(const char *progname)
00271 {
00272 printf(_("%s is the PostgreSQL server.\n\n"), progname);
00273 printf(_("Usage:\n %s [OPTION]...\n\n"), progname);
00274 printf(_("Options:\n"));
00275 #ifdef USE_ASSERT_CHECKING
00276 printf(_(" -A 1|0 enable/disable run-time assert checking\n"));
00277 #endif
00278 printf(_(" -B NBUFFERS number of shared buffers\n"));
00279 printf(_(" -c NAME=VALUE set run-time parameter\n"));
00280 printf(_(" -C NAME print value of run-time parameter, then exit\n"));
00281 printf(_(" -d 1-5 debugging level\n"));
00282 printf(_(" -D DATADIR database directory\n"));
00283 printf(_(" -e use European date input format (DMY)\n"));
00284 printf(_(" -F turn fsync off\n"));
00285 printf(_(" -h HOSTNAME host name or IP address to listen on\n"));
00286 printf(_(" -i enable TCP/IP connections\n"));
00287 printf(_(" -k DIRECTORY Unix-domain socket location\n"));
00288 #ifdef USE_SSL
00289 printf(_(" -l enable SSL connections\n"));
00290 #endif
00291 printf(_(" -N MAX-CONNECT maximum number of allowed connections\n"));
00292 printf(_(" -o OPTIONS pass \"OPTIONS\" to each server process (obsolete)\n"));
00293 printf(_(" -p PORT port number to listen on\n"));
00294 printf(_(" -s show statistics after each query\n"));
00295 printf(_(" -S WORK-MEM set amount of memory for sorts (in kB)\n"));
00296 printf(_(" -V, --version output version information, then exit\n"));
00297 printf(_(" --NAME=VALUE set run-time parameter\n"));
00298 printf(_(" --describe-config describe configuration parameters, then exit\n"));
00299 printf(_(" -?, --help show this help, then exit\n"));
00300
00301 printf(_("\nDeveloper options:\n"));
00302 printf(_(" -f s|i|n|m|h forbid use of some plan types\n"));
00303 printf(_(" -n do not reinitialize shared memory after abnormal exit\n"));
00304 printf(_(" -O allow system table structure changes\n"));
00305 printf(_(" -P disable system indexes\n"));
00306 printf(_(" -t pa|pl|ex show timings after each query\n"));
00307 printf(_(" -T send SIGSTOP to all backend processes if one dies\n"));
00308 printf(_(" -W NUM wait NUM seconds to allow attach from a debugger\n"));
00309
00310 printf(_("\nOptions for single-user mode:\n"));
00311 printf(_(" --single selects single-user mode (must be first argument)\n"));
00312 printf(_(" DBNAME database name (defaults to user name)\n"));
00313 printf(_(" -d 0-5 override debugging level\n"));
00314 printf(_(" -E echo statement before execution\n"));
00315 printf(_(" -j do not use newline as interactive query delimiter\n"));
00316 printf(_(" -r FILENAME send stdout and stderr to given file\n"));
00317
00318 printf(_("\nOptions for bootstrapping mode:\n"));
00319 printf(_(" --boot selects bootstrapping mode (must be first argument)\n"));
00320 printf(_(" DBNAME database name (mandatory argument in bootstrapping mode)\n"));
00321 printf(_(" -r FILENAME send stdout and stderr to given file\n"));
00322 printf(_(" -x NUM internal use\n"));
00323
00324 printf(_("\nPlease read the documentation for the complete list of run-time\n"
00325 "configuration settings and how to set them on the command line or in\n"
00326 "the configuration file.\n\n"
00327 "Report bugs to <[email protected]>.\n"));
00328 }
00329
00330
00331
00332 static void
00333 check_root(const char *progname)
00334 {
00335 #ifndef WIN32
00336 if (geteuid() == 0)
00337 {
00338 write_stderr("\"root\" execution of the PostgreSQL server is not permitted.\n"
00339 "The server must be started under an unprivileged user ID to prevent\n"
00340 "possible system security compromise. See the documentation for\n"
00341 "more information on how to properly start the server.\n");
00342 exit(1);
00343 }
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 if (getuid() != geteuid())
00354 {
00355 write_stderr("%s: real and effective user IDs must match\n",
00356 progname);
00357 exit(1);
00358 }
00359 #else
00360 if (pgwin32_is_admin())
00361 {
00362 write_stderr("Execution of PostgreSQL by a user with administrative permissions is not\n"
00363 "permitted.\n"
00364 "The server must be started under an unprivileged user ID to prevent\n"
00365 "possible system security compromises. See the documentation for\n"
00366 "more information on how to properly start the server.\n");
00367 exit(1);
00368 }
00369 #endif
00370 }
00371
00372
00373
00374 static char *
00375 get_current_username(const char *progname)
00376 {
00377 #ifndef WIN32
00378 struct passwd *pw;
00379
00380 pw = getpwuid(geteuid());
00381 if (pw == NULL)
00382 {
00383 write_stderr("%s: invalid effective UID: %d\n",
00384 progname, (int) geteuid());
00385 exit(1);
00386 }
00387
00388 return strdup(pw->pw_name);
00389 #else
00390 unsigned long namesize = 256 + 1;
00391 char *name;
00392
00393 name = malloc(namesize);
00394 if (!GetUserName(name, &namesize))
00395 {
00396 write_stderr("%s: could not determine user name (GetUserName failed)\n",
00397 progname);
00398 exit(1);
00399 }
00400
00401 return name;
00402 #endif
00403 }