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.18 1998/07/26 04:31:01 scrappy 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");
252 /* Some standard C libraries, including GNU, have an isblank() function.
253 Others, including Solaris, do not. So we have our own.
256 isblank(const char c)
258 return (c == ' ' || c == 9 /* tab */ );
262 next_token(FILE *fp, char *buf, const int bufsz)
264 /*--------------------------------------------------------------------------
265 Grab one token out of fp. Tokens are strings of non-blank
266 characters bounded by blank characters, beginning of line, and end
267 of line. Blank means space or tab. Return the token as *buf.
268 Leave file positioned to character immediately after the token or
269 EOF, whichever comes first. If no more tokens on line, return null
270 string as *buf and position file to beginning of next line or EOF,
271 whichever comes first.
272 --------------------------------------------------------------------------*/
274 char *eb = buf + (bufsz - 1);
276 /* Move over inital token-delimiting blanks */
277 while (isblank(c = getc(fp)));
283 * build a token in buf of next characters up to EOF, eol, or
286 while (c != EOF && c != '\n' && !isblank(c))
293 * Put back the char right after the token (putting back EOF
303 read_through_eol(FILE *file)
309 while (c != '\n' && c != EOF);
322 unsigned char FromChar,
325 for (i = 0; i < 128; i++)
327 RecodeForwTable[i] = i + 128;
328 RecodeBackTable[i] = i + 128;
331 p = getenv("PG_RECODETABLE");
334 map_file = (char *) malloc((strlen(DataDir) +
335 strlen(p) + 2) * sizeof(char));
336 sprintf(map_file, "%s/%s", DataDir, p);
337 file = fopen(map_file, "r");
350 read_through_eol(file);
353 /* Read the FromChar */
354 next_token(file, buf, sizeof(buf));
357 FromChar = strtoul(buf, 0, 0);
358 /* Read the ToChar */
359 next_token(file, buf, sizeof(buf));
362 ToChar = strtoul(buf, 0, 0);
363 RecodeForwTable[FromChar - 128] = ToChar;
364 RecodeBackTable[ToChar - 128] = FromChar;
366 read_through_eol(file);
377 convertstr(unsigned char *buff, int len, int dest)
382 for (i = 0; i < len; i++, buff++)
386 *buff = RecodeForwTable[*buff - 128];
388 *buff = RecodeBackTable[*buff - 128];
396 * GetPgUserName and SetPgUserName
398 * SetPgUserName must be called before InitPostgres, since the setuid()
401 * Replace GetPgUserName() with a lower-case version
402 * to allow use in new case-insensitive SQL (referenced
403 * in pg_proc.h). Define GetPgUserName() as a macro - tgl 97/04/26
419 if (IsUnderPostmaster)
421 /* use the (possibly) authenticated name that's provided */
422 if (!(p = getenv("PG_USER")))
423 elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
427 /* setuid() has not yet been done, see above comment */
428 if (!(pw = getpwuid(geteuid())))
429 elog(FATAL, "SetPgUserName: no entry in passwd file");
434 UserName = malloc(strlen(p) + 1);
436 #endif /* NO_SECURITY */
439 /* ----------------------------------------------------------------
440 * GetUserId and SetUserId
441 * ----------------------------------------------------------------
443 static Oid UserId = InvalidOid;
448 Assert(OidIsValid(UserId));
458 Assert(!OidIsValid(UserId));/* only once */
461 * Don't do scans if we're bootstrapping, none of the system catalogs
462 * exist yet, and they should be owned by postgres anyway.
464 if (IsBootstrapProcessingMode())
470 userName = GetPgUserName();
471 userTup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
473 if (!HeapTupleIsValid(userTup))
474 elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
477 UserId = (Oid) ((Form_pg_shadow) GETSTRUCT(userTup))->usesysid;