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.22 1998/09/01 04:33:15 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);
124 StatusBackendExit(int status)
126 /* someday, do some real cleanup and then call the LISP exit */
127 /* someday, call StatusPostmasterExit if running without postmaster */
132 * StatusPostmasterExit
136 StatusPostmasterExit(int status)
138 /* someday, do some real cleanup and then call the LISP exit */
142 /* ----------------------------------------------------------------
143 * processing mode support stuff (used to be in pmod.c)
144 * ----------------------------------------------------------------
146 static ProcessingMode Mode = NoProcessing;
149 * IsNoProcessingMode --
150 * True iff processing mode is NoProcessing.
155 return (bool) (Mode == NoProcessing);
159 * IsBootstrapProcessingMode --
160 * True iff processing mode is BootstrapProcessing.
163 IsBootstrapProcessingMode()
165 return (bool) (Mode == BootstrapProcessing);
169 * IsInitProcessingMode --
170 * True iff processing mode is InitProcessing.
173 IsInitProcessingMode()
175 return (bool) (Mode == InitProcessing);
179 * IsNormalProcessingMode --
180 * True iff processing mode is NormalProcessing.
183 IsNormalProcessingMode()
185 return (bool) (Mode == NormalProcessing);
189 * SetProcessingMode --
190 * Sets mode of processing as specified.
193 * BadArg if called with invalid mode.
196 * Mode is NoProcessing before the first time this is called.
199 SetProcessingMode(ProcessingMode mode)
201 AssertArg(mode == NoProcessing || mode == BootstrapProcessing ||
202 mode == InitProcessing || mode == NormalProcessing);
213 /* ----------------------------------------------------------------
214 * database path / name support stuff
215 * ----------------------------------------------------------------
219 SetDatabasePath(char *path)
221 /* use malloc since this is done before memory contexts are set up */
224 DatabasePath = malloc(strlen(path) + 1);
225 strcpy(DatabasePath, path);
229 SetDatabaseName(char *name)
233 DatabaseName = malloc(strlen(name) + 1);
234 strcpy(DatabaseName, name);
238 /* even if MULTIBYTE is not enabled, this function is neccesary
239 * since pg_proc.h does have.
242 getdatabaseencoding()
244 elog(ERROR, "you need to enable MB to use this function");
253 /* Some standard C libraries, including GNU, have an isblank() function.
254 Others, including Solaris, do not. So we have our own.
257 isblank(const char c)
259 return c == ' ' || c == 9 /* tab */ ;
263 next_token(FILE *fp, char *buf, const int bufsz)
265 /*--------------------------------------------------------------------------
266 Grab one token out of fp. Tokens are strings of non-blank
267 characters bounded by blank characters, beginning of line, and end
268 of line. Blank means space or tab. Return the token as *buf.
269 Leave file positioned to character immediately after the token or
270 EOF, whichever comes first. If no more tokens on line, return null
271 string as *buf and position file to beginning of next line or EOF,
272 whichever comes first.
273 --------------------------------------------------------------------------*/
275 char *eb = buf + (bufsz - 1);
277 /* Move over inital token-delimiting blanks */
278 while (isblank(c = getc(fp)));
284 * build a token in buf of next characters up to EOF, eol, or
287 while (c != EOF && c != '\n' && !isblank(c))
294 * Put back the char right after the token (putting back EOF
304 read_through_eol(FILE *file)
310 while (c != '\n' && c != EOF);
323 unsigned char FromChar,
326 for (i = 0; i < 128; i++)
328 RecodeForwTable[i] = i + 128;
329 RecodeBackTable[i] = i + 128;
332 p = getenv("PG_RECODETABLE");
335 map_file = (char *) malloc((strlen(DataDir) +
336 strlen(p) + 2) * sizeof(char));
337 sprintf(map_file, "%s/%s", DataDir, p);
338 file = fopen(map_file, "r");
351 read_through_eol(file);
354 /* Read the FromChar */
355 next_token(file, buf, sizeof(buf));
358 FromChar = strtoul(buf, 0, 0);
359 /* Read the ToChar */
360 next_token(file, buf, sizeof(buf));
363 ToChar = strtoul(buf, 0, 0);
364 RecodeForwTable[FromChar - 128] = ToChar;
365 RecodeBackTable[ToChar - 128] = FromChar;
367 read_through_eol(file);
378 convertstr(unsigned char *buff, int len, int dest)
383 for (i = 0; i < len; i++, buff++)
387 *buff = RecodeForwTable[*buff - 128];
389 *buff = RecodeBackTable[*buff - 128];
397 * GetPgUserName and SetPgUserName
399 * SetPgUserName must be called before InitPostgres, since the setuid()
402 * Replace GetPgUserName() with a lower-case version
403 * to allow use in new case-insensitive SQL (referenced
404 * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
420 if (IsUnderPostmaster)
422 /* use the (possibly) authenticated name that's provided */
423 if (!(p = getenv("PG_USER")))
424 elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
428 /* setuid() has not yet been done, see above comment */
429 if (!(pw = getpwuid(geteuid())))
430 elog(FATAL, "SetPgUserName: no entry in passwd file");
435 UserName = malloc(strlen(p) + 1);
437 #endif /* NO_SECURITY */
440 /* ----------------------------------------------------------------
441 * GetUserId and SetUserId
442 * ----------------------------------------------------------------
444 static Oid UserId = InvalidOid;
449 Assert(OidIsValid(UserId));
459 Assert(!OidIsValid(UserId));/* only once */
462 * Don't do scans if we're bootstrapping, none of the system catalogs
463 * exist yet, and they should be owned by postgres anyway.
465 if (IsBootstrapProcessingMode())
471 userName = GetPgUserName();
472 userTup = SearchSysCacheTuple(USENAME,
473 PointerGetDatum(userName),
475 if (!HeapTupleIsValid(userTup))
476 elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
479 UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;