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.16 1998/06/27 04:53:47 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);
240 /* Some standard C libraries, including GNU, have an isblank() function.
241 Others, including Solaris, do not. So we have our own.
244 isblank(const char c)
246 return (c == ' ' || c == 9 /* tab */ );
250 next_token(FILE *fp, char *buf, const int bufsz)
252 /*--------------------------------------------------------------------------
253 Grab one token out of fp. Tokens are strings of non-blank
254 characters bounded by blank characters, beginning of line, and end
255 of line. Blank means space or tab. Return the token as *buf.
256 Leave file positioned to character immediately after the token or
257 EOF, whichever comes first. If no more tokens on line, return null
258 string as *buf and position file to beginning of next line or EOF,
259 whichever comes first.
260 --------------------------------------------------------------------------*/
262 char *eb = buf + (bufsz - 1);
264 /* Move over inital token-delimiting blanks */
265 while (isblank(c = getc(fp)));
271 * build a token in buf of next characters up to EOF, eol, or
274 while (c != EOF && c != '\n' && !isblank(c))
281 * Put back the char right after the token (putting back EOF
291 read_through_eol(FILE *file)
297 while (c != '\n' && c != EOF);
310 unsigned char FromChar,
313 for (i = 0; i < 128; i++)
315 RecodeForwTable[i] = i + 128;
316 RecodeBackTable[i] = i + 128;
319 p = getenv("PG_RECODETABLE");
322 map_file = (char *) malloc((strlen(DataDir) +
323 strlen(p) + 2) * sizeof(char));
324 sprintf(map_file, "%s/%s", DataDir, p);
325 file = fopen(map_file, "r");
338 read_through_eol(file);
341 /* Read the FromChar */
342 next_token(file, buf, sizeof(buf));
345 FromChar = strtoul(buf, 0, 0);
346 /* Read the ToChar */
347 next_token(file, buf, sizeof(buf));
350 ToChar = strtoul(buf, 0, 0);
351 RecodeForwTable[FromChar - 128] = ToChar;
352 RecodeBackTable[ToChar - 128] = FromChar;
354 read_through_eol(file);
365 convertstr(unsigned char *buff, int len, int dest)
370 for (i = 0; i < len; i++, buff++)
374 *buff = RecodeForwTable[*buff - 128];
376 *buff = RecodeBackTable[*buff - 128];
384 * GetPgUserName and SetPgUserName
386 * SetPgUserName must be called before InitPostgres, since the setuid()
389 * Replace GetPgUserName() with a lower-case version
390 * to allow use in new case-insensitive SQL (referenced
391 * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
407 if (IsUnderPostmaster)
409 /* use the (possibly) authenticated name that's provided */
410 if (!(p = getenv("PG_USER")))
411 elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
415 /* setuid() has not yet been done, see above comment */
416 if (!(pw = getpwuid(geteuid())))
417 elog(FATAL, "SetPgUserName: no entry in passwd file");
422 UserName = malloc(strlen(p) + 1);
424 #endif /* NO_SECURITY */
427 /* ----------------------------------------------------------------
428 * GetUserId and SetUserId
429 * ----------------------------------------------------------------
431 static Oid UserId = InvalidOid;
436 Assert(OidIsValid(UserId));
446 Assert(!OidIsValid(UserId));/* only once */
449 * Don't do scans if we're bootstrapping, none of the system catalogs
450 * exist yet, and they should be owned by postgres anyway.
452 if (IsBootstrapProcessingMode())
458 userName = GetPgUserName();
459 userTup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
461 if (!HeapTupleIsValid(userTup))
462 elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
465 UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;