mirror of https://github.com/postgres/postgres
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
379 lines
7.5 KiB
379 lines
7.5 KiB
![]()
29 years ago
|
/*-------------------------------------------------------------------------
|
||
|
*
|
||
|
* miscinit.c--
|
||
|
* miscellanious initialization support stuff
|
||
|
*
|
||
|
* Copyright (c) 1994, Regents of the University of California
|
||
|
*
|
||
|
*
|
||
|
* IDENTIFICATION
|
||
|
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.1.1.1 1996/07/09 06:22:09 scrappy Exp $
|
||
|
*
|
||
|
*-------------------------------------------------------------------------
|
||
|
*/
|
||
|
#include <string.h>
|
||
|
#include <sys/param.h> /* for MAXPATHLEN */
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <sys/file.h>
|
||
|
#include <stdio.h>
|
||
|
#ifndef WIN32
|
||
|
#include <grp.h> /* for getgrgid */
|
||
|
#include <pwd.h> /* for getpwuid */
|
||
|
#endif /* WIN32 */
|
||
|
|
||
|
#include "postgres.h"
|
||
|
|
||
|
#include "utils/portal.h" /* for EnablePortalManager, etc. */
|
||
|
#include "utils/exc.h" /* for EnableExceptionHandling, etc. */
|
||
|
#include "utils/mcxt.h" /* for EnableMemoryContext, etc. */
|
||
|
#include "utils/elog.h"
|
||
|
#include "utils/builtins.h"
|
||
|
|
||
|
#include "miscadmin.h" /* where the declarations go */
|
||
|
|
||
|
#include "catalog/catname.h"
|
||
|
#include "catalog/pg_user.h"
|
||
|
#include "catalog/pg_proc.h"
|
||
|
#include "utils/syscache.h"
|
||
|
|
||
|
#include "storage/fd.h" /* for O_ */
|
||
|
|
||
|
/*
|
||
|
* EnableAbortEnvVarName --
|
||
|
* Enables system abort iff set to a non-empty string in environment.
|
||
|
*/
|
||
|
#define EnableAbortEnvVarName "POSTGRESABORT"
|
||
|
|
||
|
extern char *getenv(const char *name); /* XXX STDLIB */
|
||
|
|
||
|
/* from globals.c */
|
||
|
extern char *DatabaseName;
|
||
|
extern char *UserName;
|
||
|
extern char *DatabasePath;
|
||
|
|
||
|
|
||
|
/*
|
||
|
* Define USE_ENVIRONMENT to get PGDATA, etc. from environment variables.
|
||
|
* This is the default on UNIX platforms.
|
||
|
*/
|
||
|
#ifndef WIN32
|
||
|
#define USE_ENVIRONMENT
|
||
|
#endif
|
||
|
|
||
|
/* ----------------------------------------------------------------
|
||
|
* some of the 19 ways to leave postgres
|
||
|
* ----------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* ExitPostgres --
|
||
|
* Exit POSTGRES with a status code.
|
||
|
*
|
||
|
* Note:
|
||
|
* This function never returns.
|
||
|
* ...
|
||
|
*
|
||
|
* Side effects:
|
||
|
* ...
|
||
|
*
|
||
|
* Exceptions:
|
||
|
* none
|
||
|
*/
|
||
|
void
|
||
|
ExitPostgres(ExitStatus status)
|
||
|
{
|
||
|
#ifdef __SABER__
|
||
|
saber_stop();
|
||
|
#endif
|
||
|
exitpg(status);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* AbortPostgres --
|
||
|
* Abort POSTGRES dumping core.
|
||
|
*
|
||
|
* Note:
|
||
|
* This function never returns.
|
||
|
* ...
|
||
|
*
|
||
|
* Side effects:
|
||
|
* Core is dumped iff EnableAbortEnvVarName is set to a non-empty string.
|
||
|
* ...
|
||
|
*
|
||
|
* Exceptions:
|
||
|
* none
|
||
|
*/
|
||
|
void
|
||
|
AbortPostgres()
|
||
|
{
|
||
|
char *abortValue = getenv(EnableAbortEnvVarName);
|
||
|
|
||
|
#ifdef __SABER__
|
||
|
saber_stop();
|
||
|
#endif
|
||
|
|
||
|
if (PointerIsValid(abortValue) && abortValue[0] != '\0')
|
||
|
abort();
|
||
|
else
|
||
|
exitpg(FatalExitStatus);
|
||
|
}
|
||
|
|
||
|
/* ----------------
|
||
|
* StatusBackendExit
|
||
|
* ----------------
|
||
|
*/
|
||
|
void
|
||
|
StatusBackendExit(int status)
|
||
|
{
|
||
|
/* someday, do some real cleanup and then call the LISP exit */
|
||
|
/* someday, call StatusPostmasterExit if running without postmaster */
|
||
|
exitpg(status);
|
||
|
}
|
||
|
|
||
|
/* ----------------
|
||
|
* StatusPostmasterExit
|
||
|
* ----------------
|
||
|
*/
|
||
|
void
|
||
|
StatusPostmasterExit(int status)
|
||
|
{
|
||
|
/* someday, do some real cleanup and then call the LISP exit */
|
||
|
exitpg(status);
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------
|
||
|
* processing mode support stuff (used to be in pmod.c)
|
||
|
* ----------------------------------------------------------------
|
||
|
*/
|
||
|
static ProcessingMode Mode = NoProcessing;
|
||
|
|
||
|
/*
|
||
|
* IsNoProcessingMode --
|
||
|
* True iff processing mode is NoProcessing.
|
||
|
*/
|
||
|
bool
|
||
|
IsNoProcessingMode()
|
||
|
{
|
||
|
return ((bool)(Mode == NoProcessing));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* IsBootstrapProcessingMode --
|
||
|
* True iff processing mode is BootstrapProcessing.
|
||
|
*/
|
||
|
bool
|
||
|
IsBootstrapProcessingMode()
|
||
|
{
|
||
|
return ((bool)(Mode == BootstrapProcessing));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* IsInitProcessingMode --
|
||
|
* True iff processing mode is InitProcessing.
|
||
|
*/
|
||
|
bool
|
||
|
IsInitProcessingMode()
|
||
|
{
|
||
|
return ((bool)(Mode == InitProcessing));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* IsNormalProcessingMode --
|
||
|
* True iff processing mode is NormalProcessing.
|
||
|
*/
|
||
|
bool
|
||
|
IsNormalProcessingMode()
|
||
|
{
|
||
|
return ((bool)(Mode == NormalProcessing));
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* SetProcessingMode --
|
||
|
* Sets mode of processing as specified.
|
||
|
*
|
||
|
* Exceptions:
|
||
|
* BadArg if called with invalid mode.
|
||
|
*
|
||
|
* Note:
|
||
|
* Mode is NoProcessing before the first time this is called.
|
||
|
*/
|
||
|
void
|
||
|
SetProcessingMode(ProcessingMode mode)
|
||
|
{
|
||
|
AssertArg(mode == NoProcessing || mode == BootstrapProcessing ||
|
||
|
mode == InitProcessing || mode == NormalProcessing);
|
||
|
|
||
|
Mode = mode;
|
||
|
}
|
||
|
|
||
|
ProcessingMode
|
||
|
GetProcessingMode()
|
||
|
{
|
||
|
return (Mode);
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------
|
||
|
* database path / name support stuff
|
||
|
* ----------------------------------------------------------------
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
* GetDatabasePath --
|
||
|
* Returns path to database.
|
||
|
*
|
||
|
*/
|
||
|
char*
|
||
|
GetDatabasePath()
|
||
|
{
|
||
|
return DatabasePath;
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* GetDatabaseName --
|
||
|
* Returns name of database.
|
||
|
*/
|
||
|
char*
|
||
|
GetDatabaseName()
|
||
|
{
|
||
|
return DatabaseName;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
SetDatabasePath(char *path)
|
||
|
{
|
||
|
/* use malloc since this is done before memory contexts are set up */
|
||
|
if (DatabasePath)
|
||
|
free(DatabasePath);
|
||
|
DatabasePath = malloc(strlen(path)+1);
|
||
|
strcpy(DatabasePath, path);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
SetDatabaseName(char *name)
|
||
|
{
|
||
|
if (DatabaseName)
|
||
|
free (DatabaseName);
|
||
|
DatabaseName = malloc(strlen(name)+1);
|
||
|
strcpy(DatabaseName, name);
|
||
|
}
|
||
|
|
||
|
/* ----------------
|
||
|
* GetPgUserName and SetPgUserName
|
||
|
*
|
||
|
* SetPgUserName must be called before InitPostgres, since the setuid()
|
||
|
* is done there.
|
||
|
* ----------------
|
||
|
*/
|
||
|
char*
|
||
|
GetPgUserName()
|
||
|
{
|
||
|
return UserName;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
SetPgUserName()
|
||
|
{
|
||
|
#ifndef NO_SECURITY
|
||
|
char *p;
|
||
|
struct passwd *pw;
|
||
|
|
||
|
if (IsUnderPostmaster) {
|
||
|
/* use the (possibly) authenticated name that's provided */
|
||
|
if (!(p = getenv("PG_USER")))
|
||
|
elog(FATAL, "SetPgUserName: PG_USER environment variable unset");
|
||
|
} else {
|
||
|
/* setuid() has not yet been done, see above comment */
|
||
|
if (!(pw = getpwuid(geteuid())))
|
||
|
elog(FATAL, "SetPgUserName: no entry in passwd file");
|
||
|
p = pw->pw_name;
|
||
|
}
|
||
|
if (UserName)
|
||
|
free(UserName);
|
||
|
UserName = malloc(strlen(p)+1);
|
||
|
strcpy(UserName, p);
|
||
|
#endif /* NO_SECURITY */
|
||
|
|
||
|
#ifdef WIN32
|
||
|
/* XXX We'll figure out how to get the user name later */
|
||
|
if (UserName)
|
||
|
free(UserName);
|
||
|
UserName = malloc(strlen(p)+1);
|
||
|
strcpy(UserName, "postgres");
|
||
|
#endif /* WIN32 */
|
||
|
|
||
|
}
|
||
|
|
||
|
/* ----------------------------------------------------------------
|
||
|
* GetUserId and SetUserId
|
||
|
* ----------------------------------------------------------------
|
||
|
*/
|
||
|
static Oid UserId = InvalidOid;
|
||
|
|
||
|
Oid
|
||
|
GetUserId()
|
||
|
{
|
||
|
Assert(OidIsValid(UserId));
|
||
|
return(UserId);
|
||
|
}
|
||
|
|
||
|
void
|
||
|
SetUserId()
|
||
|
{
|
||
|
HeapTuple userTup;
|
||
|
char *userName;
|
||
|
|
||
|
Assert(!OidIsValid(UserId)); /* only once */
|
||
|
|
||
|
/*
|
||
|
* Don't do scans if we're bootstrapping, none of the system
|
||
|
* catalogs exist yet, and they should be owned by postgres
|
||
|
* anyway.
|
||
|
*/
|
||
|
if (IsBootstrapProcessingMode()) {
|
||
|
UserId = geteuid();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
userName = GetPgUserName();
|
||
|
userTup = SearchSysCacheTuple(USENAME, PointerGetDatum(userName),
|
||
|
0,0,0);
|
||
|
if (!HeapTupleIsValid(userTup))
|
||
|
elog(FATAL, "SetUserId: user \"%s\" is not in \"%s\"",
|
||
|
userName,
|
||
|
UserRelationName);
|
||
|
UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid;
|
||
|
}
|
||
|
|
||
|
/* ----------------
|
||
|
* GetPGHome
|
||
|
*
|
||
|
* Get POSTGRESHOME from environment, or return default.
|
||
|
* ----------------
|
||
|
*/
|
||
|
char *
|
||
|
GetPGHome()
|
||
|
{
|
||
|
#ifdef USE_ENVIRONMENT
|
||
|
char *h;
|
||
|
|
||
|
if ((h = getenv("POSTGRESHOME")) != (char *) NULL)
|
||
|
return (h);
|
||
|
#endif /* USE_ENVIRONMENT */
|
||
|
return (POSTGRESDIR);
|
||
|
|
||
|
}
|
||
|
|
||
|
char *
|
||
|
GetPGData()
|
||
|
{
|
||
|
#ifdef USE_ENVIRONMENT
|
||
|
char *p;
|
||
|
|
||
|
if ((p = getenv("PGDATA")) != (char *) NULL) {
|
||
|
return (p);
|
||
|
}
|
||
|
#endif /* USE_ENVIRONMENT */
|
||
|
return (PGDATADIR);
|
||
|
}
|