1 /*-------------------------------------------------------------------------
4 * miscellanious initialization support stuff
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.25 1999/01/17 06:18:54 momjian Exp $
12 *-------------------------------------------------------------------------
15 #include <sys/param.h> /* for MAXPATHLEN */
16 #include <sys/types.h>
21 #include <grp.h> /* for getgrgid */
22 #include <pwd.h> /* for getpwuid */
26 #include "utils/portal.h" /* for EnablePortalManager, etc. */
27 #include "utils/exc.h" /* for EnableExceptionHandling, etc. */
28 #include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
29 #include "utils/elog.h"
30 #include "utils/builtins.h"
32 #include "miscadmin.h" /* where the declarations go */
34 #include "catalog/catname.h"
35 #include "catalog/pg_shadow.h"
36 #include "catalog/pg_proc.h"
37 #include "utils/syscache.h"
39 #include "storage/fd.h" /* for O_ */
42 * EnableAbortEnvVarName --
43 * Enables system abort iff set to a non-empty string in environment.
45 #define EnableAbortEnvVarName "POSTGRESABORT"
47 extern char *getenv(const char *name); /* XXX STDLIB */
50 extern char *UserName;
53 unsigned char RecodeForwTable[128];
54 unsigned char RecodeBackTable[128];
60 * Define USE_ENVIRONMENT to get PGDATA, etc. from environment variables.
61 * This is the default on UNIX platforms.
63 #define USE_ENVIRONMENT
65 /* ----------------------------------------------------------------
66 * some of the 19 ways to leave postgres
67 * ----------------------------------------------------------------
72 * Exit POSTGRES with a status code.
75 * This function never returns.
85 ExitPostgres(ExitStatus status)
92 * Abort POSTGRES dumping core.
95 * This function never returns.
99 * Core is dumped iff EnableAbortEnvVarName is set to a non-empty string.
109 char *abortValue = getenv(EnableAbortEnvVarName);
111 if (PointerIsValid(abortValue) && abortValue[0] != '\0')
114 proc_exit(FatalExitStatus);
123 StatusBackendExit(int status)
125 /* someday, do some real cleanup and then call the LISP exit */
126 /* someday, call StatusPostmasterExit if running without postmaster */
131 * StatusPostmasterExit
135 StatusPostmasterExit(int status)
137 /* someday, do some real cleanup and then call the LISP exit */
143 /* ----------------------------------------------------------------
144 * processing mode support stuff (used to be in pmod.c)
145 * ----------------------------------------------------------------
147 static ProcessingMode Mode = NoProcessing;
151 * IsNoProcessingMode --
152 * True iff processing mode is NoProcessing.
157 return (bool) (Mode == NoProcessing);
162 * IsBootstrapProcessingMode --
163 * True iff processing mode is BootstrapProcessing.
166 IsBootstrapProcessingMode()
168 return (bool) (Mode == BootstrapProcessing);
172 * IsInitProcessingMode --
173 * True iff processing mode is InitProcessing.
176 IsInitProcessingMode()
178 return (bool) (Mode == InitProcessing);
182 * IsNormalProcessingMode --
183 * True iff processing mode is NormalProcessing.
186 IsNormalProcessingMode()
188 return (bool) (Mode == NormalProcessing);
192 * SetProcessingMode --
193 * Sets mode of processing as specified.
196 * BadArg if called with invalid mode.
199 * Mode is NoProcessing before the first time this is called.
202 SetProcessingMode(ProcessingMode mode)
204 AssertArg(mode == NoProcessing || mode == BootstrapProcessing ||
205 mode == InitProcessing || mode == NormalProcessing);
216 /* ----------------------------------------------------------------
217 * database path / name support stuff
218 * ----------------------------------------------------------------
222 SetDatabasePath(char *path)
224 /* use malloc since this is done before memory contexts are set up */
227 DatabasePath = malloc(strlen(path) + 1);
228 strcpy(DatabasePath, path);
232 SetDatabaseName(char *name)
236 DatabaseName = malloc(strlen(name) + 1);
237 strcpy(DatabaseName, name);
241 /* even if MULTIBYTE is not enabled, this function is neccesary
242 * since pg_proc.h has an entry for it.
245 getdatabaseencoding()
247 elog(ERROR, "MultiByte strings (MB) must be enabled to use this function");
256 /* Some standard C libraries, including GNU, have an isblank() function.
257 Others, including Solaris, do not. So we have our own.
260 isblank(const char c)
262 return c == ' ' || c == 9 /* tab */ ;
266 next_token(FILE *fp, char *buf, const int bufsz)
268 /*--------------------------------------------------------------------------
269 Grab one token out of fp. Tokens are strings of non-blank
270 characters bounded by blank characters, beginning of line, and end
271 of line. Blank means space or tab. Return the token as *buf.
272 Leave file positioned to character immediately after the token or
273 EOF, whichever comes first. If no more tokens on line, return null
274 string as *buf and position file to beginning of next line or EOF,
275 whichever comes first.
276 --------------------------------------------------------------------------*/
278 char *eb = buf + (bufsz - 1);
280 /* Move over inital token-delimiting blanks */
281 while (isblank(c = getc(fp)));
287 * build a token in buf of next characters up to EOF, eol, or
290 while (c != EOF && c != '\n' && !isblank(c))
297 * Put back the char right after the token (putting back EOF
307 read_through_eol(FILE *file)
313 while (c != '\n' && c != EOF);
326 unsigned char FromChar,
329 for (i = 0; i < 128; i++)
331 RecodeForwTable[i] = i + 128;
332 RecodeBackTable[i] = i + 128;
335 p = getenv("PG_RECODETABLE");
338 map_file = (char *) malloc((strlen(DataDir) +
339 strlen(p) + 2) * sizeof(char));
340 sprintf(map_file, "%s/%s", DataDir, p);
342 file = fopen(map_file, "r");
344 file = fopen(map_file, "rb");
358 read_through_eol(file);
361 /* Read the FromChar */
362 next_token(file, buf, sizeof(buf));
365 FromChar = strtoul(buf, 0, 0);
366 /* Read the ToChar */
367 next_token(file, buf, sizeof(buf));
370 ToChar = strtoul(buf, 0, 0);
371 RecodeForwTable[FromChar - 128] = ToChar;
372 RecodeBackTable[ToChar - 128] = FromChar;
374 read_through_eol(file);
385 convertstr(unsigned char *buff, int len, int dest)
390 for (i = 0; i < len; i++, buff++)
394 *buff = RecodeForwTable[*buff - 128];
396 *buff = RecodeBackTable[*buff - 128];
404 * GetPgUserName and SetPgUserName
406 * SetPgUserName must be called before InitPostgres, since the setuid()
409 * Replace GetPgUserName() with a lower-case version
410 * to allow use in new case-insensitive SQL (referenced
411 * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
427 if (IsUnderPostmaster)
429 /* use the (possibly) authenticated name that's provided */
430 if (!(p = getenv("PG_USER")))
431 elog(FATAL, "SetPgUserName: PG_USER environment variable is unset");
435 /* setuid() has not yet been done, see above comment */
436 if (!(pw = getpwuid(geteuid())))
437 elog(FATAL, "SetPgUserName: no entry in host passwd file");
442 UserName = malloc(strlen(p) + 1);
444 #endif /* NO_SECURITY */
447 /* ----------------------------------------------------------------
448 * GetUserId and SetUserId
449 * ----------------------------------------------------------------
451 static Oid UserId = InvalidOid;
456 Assert(OidIsValid(UserId));
466 Assert(!OidIsValid(UserId));/* only once */
469 * Don't do scans if we're bootstrapping, none of the system catalogs
470 * exist yet, and they should be owned by postgres anyway.
472 if (IsBootstrapProcessingMode())
478 userName = GetPgUserName();
479 userTup = SearchSysCacheTuple(USENAME,
480 PointerGetDatum(userName),
482 if (!HeapTupleIsValid(userTup))
483 elog(FATAL, "SetUserId: user '%s' is not in '%s'",
486 UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;