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.37 1999/11/24 16:52:42 momjian Exp $
12 *-------------------------------------------------------------------------
14 #include <sys/param.h>
15 #include <sys/types.h>
23 #include "catalog/catname.h"
24 #include "catalog/pg_shadow.h"
25 #include "miscadmin.h"
26 #include "utils/syscache.h"
30 * EnableAbortEnvVarName
31 * Enables system abort iff set to a non-empty string in environment.
33 #define EnableAbortEnvVarName "POSTGRESABORT"
35 extern char *getenv(const char *name); /* XXX STDLIB */
38 extern char *UserName;
41 unsigned char RecodeForwTable[128];
42 unsigned char RecodeBackTable[128];
48 * Define USE_ENVIRONMENT to get PGDATA, etc. from environment variables.
49 * This is the default on UNIX platforms.
51 #define USE_ENVIRONMENT
53 /* ----------------------------------------------------------------
54 * some of the 19 ways to leave postgres
55 * ----------------------------------------------------------------
60 * Exit POSTGRES with a status code.
63 * This function never returns.
73 ExitPostgres(ExitStatus status)
80 * Abort POSTGRES dumping core.
83 * This function never returns.
87 * Core is dumped iff EnableAbortEnvVarName is set to a non-empty string.
97 char *abortValue = getenv(EnableAbortEnvVarName);
99 if (PointerIsValid(abortValue) && abortValue[0] != '\0')
102 proc_exit(FatalExitStatus);
111 StatusBackendExit(int status)
113 /* someday, do some real cleanup and then call the LISP exit */
114 /* someday, call StatusPostmasterExit if running without postmaster */
119 * StatusPostmasterExit
123 StatusPostmasterExit(int status)
125 /* someday, do some real cleanup and then call the LISP exit */
132 /* ----------------------------------------------------------------
133 * processing mode support stuff (used to be in pmod.c)
134 * ----------------------------------------------------------------
136 static ProcessingMode Mode = InitProcessing;
139 * IsBootstrapProcessingMode
140 * True iff processing mode is BootstrapProcessing.
143 IsBootstrapProcessingMode()
145 return (bool) (Mode == BootstrapProcessing);
149 * IsInitProcessingMode
150 * True iff processing mode is InitProcessing.
153 IsInitProcessingMode()
155 return (bool) (Mode == InitProcessing);
159 * IsNormalProcessingMode
160 * True iff processing mode is NormalProcessing.
163 IsNormalProcessingMode()
165 return (bool) (Mode == NormalProcessing);
170 * Sets mode of processing as specified.
173 * BadArg if called with invalid mode.
176 * Mode is InitProcessing before the first time this is called.
179 SetProcessingMode(ProcessingMode mode)
181 AssertArg(mode == BootstrapProcessing || mode == InitProcessing ||
182 mode == NormalProcessing);
193 /* ----------------------------------------------------------------
194 * database path / name support stuff
195 * ----------------------------------------------------------------
199 SetDatabasePath(char *path)
201 /* use malloc since this is done before memory contexts are set up */
204 DatabasePath = malloc(strlen(path) + 1);
205 strcpy(DatabasePath, path);
209 SetDatabaseName(char *name)
213 DatabaseName = malloc(strlen(name) + 1);
214 strcpy(DatabaseName, name);
218 /* even if MULTIBYTE is not enabled, this function is neccesary
219 * since pg_proc.h has an entry for it.
222 getdatabaseencoding()
224 elog(ERROR, "MultiByte strings (MB) must be enabled to use this function");
233 /* Some standard C libraries, including GNU, have an isblank() function.
234 Others, including Solaris, do not. So we have our own.
237 isblank(const char c)
239 return c == ' ' || c == 9 /* tab */ ;
243 next_token(FILE *fp, char *buf, const int bufsz)
245 /*--------------------------------------------------------------------------
246 Grab one token out of fp. Tokens are strings of non-blank
247 characters bounded by blank characters, beginning of line, and end
248 of line. Blank means space or tab. Return the token as *buf.
249 Leave file positioned to character immediately after the token or
250 EOF, whichever comes first. If no more tokens on line, return null
251 string as *buf and position file to beginning of next line or EOF,
252 whichever comes first.
253 --------------------------------------------------------------------------*/
255 char *eb = buf + (bufsz - 1);
257 /* Move over inital token-delimiting blanks */
258 while (isblank(c = getc(fp)));
264 * build a token in buf of next characters up to EOF, eol, or
267 while (c != EOF && c != '\n' && !isblank(c))
274 * Put back the char right after the token (putting back EOF
284 read_through_eol(FILE *file)
290 while (c != '\n' && c != EOF);
303 unsigned char FromChar,
306 for (i = 0; i < 128; i++)
308 RecodeForwTable[i] = i + 128;
309 RecodeBackTable[i] = i + 128;
312 p = getenv("PG_RECODETABLE");
315 map_file = (char *) malloc((strlen(DataDir) +
316 strlen(p) + 2) * sizeof(char));
317 sprintf(map_file, "%s/%s", DataDir, p);
319 file = AllocateFile(map_file, "r");
321 file = AllocateFile(map_file, "rb");
335 read_through_eol(file);
338 /* Read the FromChar */
339 next_token(file, buf, sizeof(buf));
342 FromChar = strtoul(buf, 0, 0);
343 /* Read the ToChar */
344 next_token(file, buf, sizeof(buf));
347 ToChar = strtoul(buf, 0, 0);
348 RecodeForwTable[FromChar - 128] = ToChar;
349 RecodeBackTable[ToChar - 128] = FromChar;
351 read_through_eol(file);
362 convertstr(unsigned char *buff, int len, int dest)
367 for (i = 0; i < len; i++, buff++)
371 *buff = RecodeForwTable[*buff - 128];
373 *buff = RecodeBackTable[*buff - 128];
381 * GetPgUserName and SetPgUserName
383 * SetPgUserName must be called before InitPostgres, since the setuid()
386 * Replace GetPgUserName() with a lower-case version
387 * to allow use in new case-insensitive SQL (referenced
388 * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
404 if (IsUnderPostmaster)
406 /* use the (possibly) authenticated name that's provided */
407 if (!(p = getenv("PG_USER")))
408 elog(FATAL, "SetPgUserName: PG_USER environment variable is unset");
412 /* setuid() has not yet been done, see above comment */
413 if (!(pw = getpwuid(geteuid())))
414 elog(FATAL, "SetPgUserName: no entry in host passwd file");
419 UserName = malloc(strlen(p) + 1);
421 #endif /* NO_SECURITY */
424 /* ----------------------------------------------------------------
425 * GetUserId and SetUserId
426 * ----------------------------------------------------------------
428 static Oid UserId = InvalidOid;
433 Assert(OidIsValid(UserId));
443 Assert(!OidIsValid(UserId));/* only once */
446 * Don't do scans if we're bootstrapping, none of the system catalogs
447 * exist yet, and they should be owned by postgres anyway.
449 if (IsBootstrapProcessingMode())
455 userName = GetPgUserName();
456 userTup = SearchSysCacheTuple(SHADOWNAME,
457 PointerGetDatum(userName),
459 if (!HeapTupleIsValid(userTup))
460 elog(FATAL, "SetUserId: user '%s' is not in '%s'",
463 UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;