head 1.20; access; symbols release_4_2:1.20 aix_ok:1.17 Version_2_1:1.2; locks; strict; comment @ * @; 1.20 date 94.06.16.03.23.06; author aoki; state Exp; branches; next 1.19; 1.19 date 94.02.17.03.24.57; author sklower; state Exp; branches; next 1.18; 1.18 date 93.12.12.23.20.52; author aoki; state Exp; branches; next 1.17; 1.17 date 93.06.23.21.09.35; author aoki; state Exp; branches; next 1.16; 1.16 date 93.06.23.20.47.45; author marc; state Exp; branches; next 1.15; 1.15 date 93.02.20.06.00.18; author aoki; state Exp; branches; next 1.14; 1.14 date 93.02.20.03.13.45; author aoki; state Exp; branches; next 1.13; 1.13 date 93.01.29.05.08.36; author aoki; state Exp; branches; next 1.12; 1.12 date 93.01.05.02.31.00; author aoki; state Exp; branches; next 1.11; 1.11 date 92.12.29.01.48.28; author aoki; state Exp; branches; next 1.10; 1.10 date 92.12.19.00.23.38; author marc; state Exp; branches; next 1.9; 1.9 date 92.12.18.21.13.57; author mao; state Exp; branches; next 1.8; 1.8 date 92.09.05.23.42.29; author mao; state Exp; branches; next 1.7; 1.7 date 92.04.03.19.49.30; author mao; state Exp; branches; next 1.6; 1.6 date 92.04.02.19.14.15; author mer; state Exp; branches; next 1.5; 1.5 date 91.11.12.20.20.29; author mer; state Exp; branches; next 1.4; 1.4 date 91.09.09.23.57.48; author mao; state Exp; branches; next 1.3; 1.3 date 91.09.06.12.31.20; author hong; state Exp; branches; next 1.2; 1.2 date 90.10.10.00.42.37; author cimarron; state Exp; branches; next 1.1; 1.1 date 90.10.05.16.01.14; author cimarron; state Exp; branches; next ; desc @@ 1.20 log @O_ flag @ text @/* ---------------------------------------------------------------- * FILE * miscinit.c * * DESCRIPTION * miscellanious initialization support stuff * * INTERFACE ROUTINES * * NOTES * * IDENTIFICATION * $Header: /import/faerie/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.19 1994/02/17 03:24:57 sklower Exp aoki $ * ---------------------------------------------------------------- */ #include /* for getgrgid */ #include /* for getpwuid */ #include #include /* for MAXPATHLEN */ #include #include #include #include "tmp/postgres.h" #include "tmp/portal.h" /* for EnablePortalManager, etc. */ #include "utils/exc.h" /* for EnableExceptionHandling, etc. */ #include "utils/mcxt.h" /* for EnableMemoryContext, etc. */ #include "utils/log.h" #include "tmp/miscadmin.h" #include "catalog/catname.h" #include "catalog/pg_user.h" #include "catalog/pg_proc.h" #include "catalog/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 ARGS((const char *name)); /* XXX STDLIB */ /* ---------------------------------------------------------------- * some of the 19 ways to leave postgres * ---------------------------------------------------------------- */ /* ---------------- * ExitPostgres * ---------------- */ void ExitPostgres(status) ExitStatus status; { #ifdef __SABER__ saber_stop(); #endif exitpg(status); } /* ---------------- * AbortPostgres * ---------------- */ void AbortPostgres() { String abortValue = getenv(EnableAbortEnvVarName); #ifdef __SABER__ saber_stop(); #endif if (PointerIsValid(abortValue) && abortValue[0] != '\0') abort(); else exitpg(FatalExitStatus); } /* ---------------- * StatusBackendExit * ---------------- */ void StatusBackendExit(status) 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(status) 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; bool IsNoProcessingMode() { return ((bool)(Mode == NoProcessing)); } bool IsBootstrapProcessingMode() { return ((bool)(Mode == BootstrapProcessing)); } bool IsInitProcessingMode() { return ((bool)(Mode == InitProcessing)); } bool IsNormalProcessingMode() { return ((bool)(Mode == NormalProcessing)); } void SetProcessingMode(mode) ProcessingMode mode; { AssertArg(mode == NoProcessing || mode == BootstrapProcessing || mode == InitProcessing || mode == NormalProcessing); Mode = mode; } ProcessingMode GetProcessingMode() { return (Mode); } /* ---------------------------------------------------------------- * database path / name support stuff * ---------------------------------------------------------------- */ static String DatabasePath = NULL; static String DatabaseName = NULL; String GetDatabasePath() { return DatabasePath; } String GetDatabaseName() { return DatabaseName; } void SetDatabasePath(path) String path; { DatabasePath = path; } void SetDatabaseName(name) String name; { extern NameData MyDatabaseNameData; /* ---------------- * save the database name in MyDatabaseNameData. * XXX we currently have MyDatabaseName, MyDatabaseNameData and * DatabaseName. What uses each of these?? this duality should * be eliminated! -cim 10/5/90 * ---------------- */ strncpy(&MyDatabaseNameData, name, sizeof(NameData)); DatabaseName = (String) &MyDatabaseNameData; } /* ---------------- * GetUserName and SetUserName * * SetUserName must be called before InitPostgres, since the setuid() * is done there. * ---------------- */ static struct UserNameStruct { char data[NAMEDATALEN + 1]; } UserName = { "" }; void GetUserName(namebuf) Name namebuf; { Assert(UserName.data[0]); Assert(PointerIsValid((Pointer) namebuf)); (void) strncpy(namebuf->data, UserName.data, sizeof(*namebuf)); } void SetUserName() { char *p; struct passwd *pw; Assert(!UserName.data[0]); /* only once */ if (IsUnderPostmaster) { /* use the (possibly) authenticated name that's provided */ if (!(p = getenv("PG_USER"))) elog(FATAL, "SetUserName: PG_USER environment variable unset"); } else { /* setuid() has not yet been done, see above comment */ if (!(pw = getpwuid(getuid()))) elog(FATAL, "SetUserName: no entry in passwd file"); p = pw->pw_name; } (void) strncpy(UserName.data, p, sizeof(UserName)); UserName.data[sizeof(UserName)-1] = 0; Assert(UserName.data[0]); } /* ---------------------------------------------------------------- * GetUserId and SetUserId * ---------------------------------------------------------------- */ static ObjectId UserId = InvalidObjectId; ObjectId GetUserId() { Assert(ObjectIdIsValid(UserId)); return(UserId); } void SetUserId() { HeapTuple userTup; NameData user; Assert(!ObjectIdIsValid(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 = getuid(); return; } GetUserName(&user); userTup = SearchSysCacheTuple(USENAME, user.data, NULL, NULL, NULL); if (!HeapTupleIsValid(userTup)) elog(FATAL, "SetUserId: user \"%-.*s\" is not in \"%-.*s\"", sizeof(NameData), user.data, sizeof(NameData), UserRelationName); UserId = (ObjectId) ((Form_pg_user) GETSTRUCT(userTup))->usesysid; } /* ---------------- * GetPGHome * * Get POSTGRESHOME from environment, or return default. * ---------------- */ char * GetPGHome() { char *h; #ifdef USE_ENVIRONMENT if ((h = getenv("POSTGRESHOME")) != (char *) NULL) return (h); #endif return (POSTGRESDIR); } char * GetPGData() { char *p; char *h; static char data[MAXPGPATH]; if ((p = getenv("PGDATA")) != (char *) NULL) { return (p); } return (DATADIR); } /* * ValidateBackend -- validate "path" as a POSTGRES executable file * * returns 0 if the file is found and no error is encountered. * -1 if the regular file "path" does not exist or cannot be executed. * -2 if the file is otherwise valid but cannot be read. */ ValidateBackend(path) char *path; { struct stat buf; uid_t euid; struct group *gp; struct passwd *pwp; int i; int is_r = 0; int is_x = 0; int in_grp = 0; /* * Ensure that the file exists and is a regular file. * * XXX if you have a broken system where stat() looks at the symlink * instead of the underlying file, you lose. */ if (strlen(path) >= MAXPGPATH) { if (DebugLvl > 1) fprintf(stderr, "ValidateBackend: pathname \"%s\" is too long\n", path); return(-1); } if (stat(path, &buf) < 0) { if (DebugLvl > 1) fprintf(stderr, "ValidateBackend: can't stat \"%s\"\n", path); return(-1); } if (!(buf.st_mode & S_IFREG)) { if (DebugLvl > 1) fprintf(stderr, "ValidateBackend: \"%s\" is not a regular file\n", path); return(-1); } /* * Ensure that we are using an authorized backend. * * XXX I'm open to suggestions here. I would like to enforce ownership * of backends by user "postgres" but people seem to like to run * as users other than "postgres"... */ /* * Ensure that the file is both executable and readable (required for * dynamic loading). * * We use the effective uid here because the backend will not have * executed setuid() by the time it calls this routine. */ euid = geteuid(); if (euid == buf.st_uid) { is_r = buf.st_mode & S_IRUSR; is_x = buf.st_mode & S_IXUSR; if (DebugLvl > 1 && !(is_r && is_x)) fprintf(stderr, "ValidateBackend: \"%s\" is not user read/execute\n", path); return(is_x ? (is_r ? 0 : -2) : -1); } if (pwp = getpwuid(euid)) { if (pwp->pw_gid == buf.st_gid) { ++in_grp; } else if (pwp->pw_name && (gp = getgrgid(buf.st_gid))) { for (i = 0; gp->gr_mem[i]; ++i) { if (!strcmp(gp->gr_mem[i], pwp->pw_name)) { ++in_grp; break; } } } if (in_grp) { is_r = buf.st_mode & S_IRGRP; is_x = buf.st_mode & S_IXGRP; if (DebugLvl > 1 && !(is_r && is_x)) fprintf(stderr, "ValidateBackend: \"%s\" is not group read/execute\n", path); return(is_x ? (is_r ? 0 : -2) : -1); } } is_r = buf.st_mode & S_IROTH; is_x = buf.st_mode & S_IXOTH; if (DebugLvl > 1 && !(is_r && is_x)) fprintf(stderr, "ValidateBackend: \"%s\" is not other read/execute\n", path); return(is_x ? (is_r ? 0 : -2) : -1); } /* * FindBackend -- find an absolute path to a valid backend executable * * The reason we have to work so hard to find an absolute path is that * we need to feed the backend server the location of its actual * executable file -- otherwise, we can't do dynamic loading. */ FindBackend(backend, argv0) char *backend, *argv0; { char buf[MAXPGPATH + 2]; char *p; char *path, *startp, *endp; int pathlen; /* * for the postmaster: * First try: use the backend that's located in the same directory * as the postmaster, if it was invoked with an explicit path. * Presumably the user used an explicit path because it wasn't in * PATH, and we don't want to use incompatible executables. * * This has the neat property that it works for installed binaries, * old source trees (obj/support/post{master,gres}) and new marc * source trees (obj/post{master,gres}) because they all put the * two binaries in the same place. * * for the backend server: * First try: if we're given some kind of path, use it (making sure * that a relative path is made absolute before returning it). */ if (argv0 && (p = strrchr(argv0, '/')) && *++p) { if (*argv0 == '/' || !getcwd(buf, MAXPGPATH)) buf[0] = '\0'; else (void) strcat(buf, "/"); (void) strcat(buf, argv0); if (IsPostmaster) { /* change "postmaster" to "postgres" */ p = strrchr(buf, '/'); (void) strcpy(++p, "postgres"); } if (!ValidateBackend(buf)) { (void) strncpy(backend, buf, MAXPGPATH); if (DebugLvl) fprintf(stderr, "FindBackend: found \"%s\" using argv[0]\n", backend); return(0); } fprintf(stderr, "FindBackend: invalid backend \"%s\"\n", buf); return(-1); } /* * Second try: since no explicit path was supplied, the user must * have been relying on PATH. We'll use the same PATH. */ if ((p = getenv("PATH")) && *p) { if (DebugLvl) fprintf(stderr, "FindBackend: searching PATH ...\n"); pathlen = strlen(p); if (!(path = malloc(pathlen + 1))) elog(FATAL, "FindBackend: malloc failed"); (void) strcpy(path, p); for (startp = path, endp = strchr(path, ':'); startp && *startp; startp = endp + 1, endp = strchr(startp, ':')) { if (startp == endp) /* it's a "::" */ continue; if (endp) *endp = '\0'; if (*startp == '/' || !getcwd(buf, MAXPGPATH)) buf[0] = '\0'; (void) strcat(buf, startp); (void) strcat(buf, "/postgres"); switch (ValidateBackend(buf)) { case 0: /* found ok */ (void) strncpy(backend, buf, MAXPGPATH); if (DebugLvl) fprintf(stderr, "FindBackend: found \"%s\" using PATH\n", backend); free(path); return(0); case -1: /* wasn't even a candidate, keep looking */ break; case -2: /* found but disqualified */ fprintf(stderr, "FindBackend: could not read backend \"%s\"\n", buf); free(path); return(-1); } if (!endp) /* last one */ break; } free(path); } #ifdef USE_ENVIRONMENT /* * Desperation time: try the ol' POSTGRESHOME hack. */ if (p = getenv("POSTGRESHOME")) { (void) strcpy(buf, p); (void) strcat(buf, "/bin/postgres"); if (!ValidateBackend(buf)) { (void) strncpy(backend, buf, MAXPGPATH); if (DebugLvl) fprintf(stderr, "FindBackend: found \"%s\" through POSTGRESHOME\n", backend); return(0); } } #endif /* USE_ENVIRONMENT */ fprintf(stderr, "FindBackend: could not find a backend to execute...\n"); return(-1); } static struct groupInfo { gid_t *list; int glim; int ngroups; char *name; int namelen; uid_t uid; gid_t list_initial[32]; }; static struct groupInfo groupInfo = { groupInfo.list_initial, sizeof(groupInfo.list_initial)/sizeof(groupInfo.list_initial[0]), }; static void putGroup(gid) gid_t gid; { if (groupInfo.ngroups == (groupInfo.glim - 1)) { int oldsize = groupInfo.glim * sizeof(gid_t); gid_t *newlist = malloc(2 * oldsize); if (newlist == 0) return; bcopy((char *)groupInfo.list, (char *)newlist, oldsize); if (groupInfo.list != groupInfo.list_initial) free(groupInfo.list); groupInfo.list = newlist; groupInfo.glim *= 2; } groupInfo.list[groupInfo.ngroups] = gid; groupInfo.ngroups++; } static int putGroups(name) char *name; { struct passwd *pw; struct group *gr; char **gr_mem; if (groupInfo.ngroups != 0 || (pw = getpwnam(name)) == 0) return 0; groupInfo.uid = pw->pw_uid; putGroup(pw->pw_gid); setgrent(); while (gr = getgrent()) { if (gr->gr_gid == pw->pw_gid) continue; for (gr_mem = gr->gr_mem; *gr_mem; gr_mem++) if (strcmp(*gr_mem, name) == 0) { putGroup(gr->gr_gid); break; /* out of "for", but not "while" */ } } endgrent(); endpwent(); return 1; } #define SearchPerm S_IXUSR #define WritePerm S_IWUSR #define ReadPerm S_IRUSR #define UserPerm (SearchPerm|WritePerm|ReadPerm) #define CreatePerm S_IFDIR static int pathPerm(path, isDir) char *path; int isDir; { struct stat st_buf; int i; if ((stat(path, &st_buf) < 0) || (isDir && ((st_buf.st_mode & S_IFMT) != S_IFDIR)) || (isDir == 0 && ((st_buf.st_mode & S_IFMT) == S_IFDIR))) return 0; if (groupInfo.uid == st_buf.st_uid) return (UserPerm & st_buf.st_mode); for (i = 0; i < groupInfo.ngroups; i++) if (st_buf.st_gid == groupInfo.list[i]) return (UserPerm & (st_buf.st_mode << 3)); return (UserPerm & ((st_buf.st_mode) << 6)); } int CheckPathAccess(path, name, open_mode) char *path, *name; int open_mode; { char *cp, *last, *next; int dirmode, filemode, namelen; struct stat st_buf; if (name == 0) name = UserName.data; namelen = strlen(name) + 1; if (groupInfo.name && strcmp(groupInfo.name, name)) { groupInfo.ngroups = 0; if (groupInfo.namelen < namelen) { free(groupInfo.name); groupInfo.name = 0; } else strcpy(groupInfo.name, name); } if (groupInfo.name == 0) { groupInfo.namelen = namelen; groupInfo.name = (char *)malloc(namelen); strcpy(groupInfo.name, name); } if (path[0] != '/' || (groupInfo.ngroups == 0 && putGroups(name) == 0)) return -1; dirmode = pathPerm("/", 1); for (last = cp = path;;) { if ((dirmode & SearchPerm) == 0) return -1; *cp = '/'; cp = strchr(cp + 1, '/'); if (cp == 0) break; *cp = 0; dirmode = pathPerm(path, 1); last = cp; } *last = '/'; if (stat(path, &st_buf) < 0) return ((dirmode & WritePerm) ? open_mode : -1); filemode = pathPerm(path, 0); switch (filemode & (S_IWUSR|S_IRUSR)) { case 0: return (-1); /* permission has been revoked */ case S_IRUSR: open_mode &= ~(O_ACCMODE|O_APPEND|O_CREAT|O_TRUNC); open_mode |= O_RDONLY; break; case S_IWUSR: open_mode &= ~O_ACCMODE; open_mode |= O_WRONLY; break; case (S_IWUSR|S_IRUSR): break; /* usr can do what s/he will */ } return open_mode; } @ 1.19 log @Add manual access check for files so that both postgres and the user are considered. (Currently used by External Large Object stuff). @ text @d13 1 a13 1 * $Header: /faerie/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.18 1993/12/12 23:20:52 aoki Exp $ d38 3 @ 1.18 log @used -* instead of -.* again.. @ text @d13 1 a13 1 * $Header: /faerie/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.17 1993/06/23 21:09:35 aoki Exp aoki $ d23 1 d205 1 a205 1 static NameData UserName = { "" }; d214 1 a214 1 (void) strncpy(namebuf->data, UserName.data, sizeof(NameData)); d235 2 a236 1 (void) strncpy(UserName.data, p, sizeof(NameData)); d527 151 @ 1.17 log @changed use of getwd to getcwd for portability @ text @d13 1 a13 1 * $Header: /home2/aoki/hpux/src/backend/utils/init/RCS/miscinit.c,v 1.16 1993/06/23 20:47:45 marc Exp aoki $ d273 1 a273 1 elog(FATAL, "SetUserId: user \"%-*s\" is not in \"%-*s\"", @ 1.16 log @more specific error message @ text @d13 1 a13 1 * $Header: /usr/local/devel/postgres.alpha/src/backend/utils/init/RCS/miscinit.c,v 1.15 1993/02/20 06:00:18 aoki Exp marc $ d418 1 a418 1 char buf[MAXPATHLEN]; d440 1 a440 1 if (*argv0 == '/' || !getwd(buf)) d479 1 a479 1 if (*startp == '/' || !getwd(buf)) @ 1.15 log @make relative PATH paths absolute @ text @d13 1 a13 1 * $Header: /home2/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.14 1993/02/20 03:13:45 aoki Exp aoki $ d336 1 a336 3 if (strlen(path) >= MAXPGPATH || (stat(path, &buf) < 0) || !(buf.st_mode & S_IFREG)) { d338 12 @ 1.14 log @changed strings.h to string.h (since only sysV string routines are used) to pacify sunos @ text @d13 1 a13 1 * $Header: /home2/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.13 1993/01/29 05:08:36 aoki Exp aoki $ d469 3 a471 1 (void) strcpy(buf, startp); @ 1.13 log @changed interface to ValidBackend (now ValidateBackend). had to define a notion of "valid in all respects except readability" since it is essentially a fatal error .. @ text @a0 1 d13 1 a13 1 * $Header: /home2/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.12 1993/01/05 02:31:00 aoki Exp aoki $ d19 1 a19 1 #include @ 1.12 log @added functions to get around need for PG_username. @ text @d14 1 a14 1 * $Header: /home2/aoki/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.11 1992/12/29 01:48:28 aoki Exp aoki $ d18 3 a20 1 #include /* for getpwent */ d22 1 a22 1 #include /* for dev_t */ d44 1 a44 2 typedef String EnvVarName; extern String getenv ARGS((EnvVarName name)); a221 1 extern char *getenv(); /* XXX STDLIB */ d230 1 a230 1 /* setuid() has not yet been done */ d313 84 a396 27 * ValidBackend -- is "path" a valid POSTGRES executable file? */ ValidBackend(path) char *path; { struct stat buf; char *p; extern char *rindex(); /* Ensure that the file exists and is executable. */ if (strlen(path) > MAXPGPATH || (stat(path, &buf) < 0) || !(buf.st_mode & S_IEXEC)) return(FALSE); /* Ensure that we are using an authorized backend */ /* * XXX this is bogus, but it's better than nothing for now. * you used to be able to run emacs by dinking the postmaster * with the right packets. */ if (!(p = rindex(path, '/')) || strncmp(++p, "postgres", 8)) return(FALSE); return(TRUE); d407 1 a407 1 char *backend, *argv0; d409 65 a473 36 char buf[MAXPATHLEN]; char *p; char *path, *startp, *endp; int pathlen; extern char *index(), *rindex(); /* * for the postmaster: * First try: use the backend that's located in the same directory * as the postmaster, if it was invoked with an explicit path. * Presumably the user used an explicit path because it wasn't in * PATH, and we don't want to use incompatible executables. * * This has the neat property that it works for installed binaries, * old source trees (obj/support/post{master,gres}) and new marc * source trees (obj/post{master,gres}) because they all put the * two binaries in the same place. * * for the backend server: * First try: if we're given some kind of path, use it (making sure * that a relative path is made absolute before returning it). */ if (argv0 && (p = rindex(argv0, '/')) && *++p) { if (*argv0 == '/' || !getwd(buf)) buf[0] = '\0'; else (void) strcat(buf, "/"); (void) strcat(buf, argv0); if (IsPostmaster) { /* change "postmaster" to "postgres" */ p = rindex(buf, '/'); (void) strcpy(++p, "postgres"); } if (!ValidBackend(buf)) { fprintf(stderr, "FindBackend: could not find postgres using the pathname provided\n"); return(-1); } d476 3 a478 2 fprintf(stderr, "FindBackend: found backend \"%s\" through argv[0]\n", backend); d480 5 a484 31 } /* * Second try: since no explicit path was supplied, the user must * have been relying on PATH. We'll use the same PATH. */ if ((p = getenv("PATH")) && *p) { pathlen = strlen(p); if (!(path = malloc(pathlen + 1))) elog(FATAL, "FindBackend: malloc failed"); (void) strcpy(path, p); for (startp = path, endp = index(path, ':'); startp && *startp; startp = endp + 1, endp = index(startp, ':')) { if (startp == endp) /* it's a "::" */ continue; if (endp) *endp = '\0'; (void) strcpy(buf, startp); (void) strcat(buf, "/postgres"); if (ValidBackend(buf)) { (void) strncpy(backend, buf, MAXPGPATH); free(path); if (DebugLvl) fprintf(stderr, "FindBackend: found backend \"%s\" through PATH\n", backend); return(0); } if (!endp) /* last one */ break; } d486 4 d491 3 a493 1 d495 12 a506 13 /* * Desperation time: try the ol' POSTGRESHOME hack. */ if (p = getenv("POSTGRESHOME")) { (void) strcpy(buf, p); (void) strcat(buf, "/bin/postgres"); if (ValidBackend(buf)) { (void) strncpy(backend, buf, MAXPGPATH); if (DebugLvl) fprintf(stderr, "FindBackend: found backend \"%s\" through POSTGRESHOME\n", backend); return(0); } d508 1 d510 3 a512 3 fprintf(stderr, "FindBackend: could not find a backend to execute...\n"); return(-1); @ 1.11 log @added pg_username (from char.c), added backend-finding code. @ text @d14 1 a14 1 * $Header: /home2/aoki/postgres/utils/init/RCS/miscinit.c,v 1.10 1992/12/19 00:23:38 marc Exp aoki $ d18 1 d35 1 a35 2 #include "access/skey.h" #include "utils/rel.h" a153 25 * ReinitAtFirstTransaction() * InitAtFirstTransaction() * * This is obviously some half-finished hirohama-ism that does * nothing and should be removed. * ---------------------------------------------------------------- */ void ReinitAtFirstTransaction() { elog(FATAL, "ReinitAtFirstTransaction: not implemented, yet"); } void InitAtFirstTransaction() { if (TransactionInitWasProcessed) { ReinitAtFirstTransaction(); } /* Walk the relcache? */ TransactionInitWasProcessed = true; /* XXX ...InProgress also? */ } /* ---------------------------------------------------------------- d192 1 a192 1 strncpy(&MyDatabaseNameData, name, 16); d197 43 d241 1 a241 1 * GetUserId and SetUserId support (used to be in pusr.c) a245 4 /* ---------------- * GetUserId * ---------------- */ d249 2 a250 2 AssertState(ObjectIdIsValid(UserId)); return (UserId); a252 5 /* ---------------- * SetUserId * ---------------- */ d256 2 a257 4 HeapScanDesc s; ScanKeyData key; Relation userRel; HeapTuple userTup; d259 2 d266 1 a266 2 if (IsBootstrapProcessingMode()) { d271 2 a272 9 userRel = heap_openr(UserRelationName); ScanKeyEntryInitialize(&key.data[0], (bits16)0x0, Anum_pg_user_usename, Character16EqualRegProcedure, (Datum)PG_username); s = heap_beginscan(userRel,0,NowTimeQual,1,(ScanKey)&key); userTup = heap_getnext(s, 0, (Buffer *)NULL); d274 3 a276 16 { elog(FATAL, "User %s is not in %s", PG_username, UserRelationName); } UserId = (ObjectId) ((Form_pg_user)GETSTRUCT(userTup))->usesysid; heap_endscan(s); heap_close(userRel); } /* ---------------- * pg_username * ---------------- */ char * pg_username() { return(PG_username); d384 3 a386 6 if (ValidBackend(buf)) { (void) strncpy(backend, buf, MAXPGPATH); if (!Quiet) fprintf(stderr, "FindBackend: found backend \"%s\" through argv[0]\n", backend); return(0); d388 5 d416 1 a416 1 if (!Quiet) d436 1 a436 1 if (!Quiet) @ 1.10 log @mao changes to get processing mode @ text @d14 1 a14 1 * $Header: /usr/local/dev/postgres/newtree/src/backend/utils/init/RCS/miscinit.c,v 1.8 1992/09/05 23:42:29 mao Exp marc $ d18 4 d31 1 a243 3 extern Name UserRelationName; extern char *PG_username; d282 10 d322 134 @ 1.9 log @add GetProcessingMode() so we can tell if it's init or bootstrap time and do the right thing with catalog indices @ text @d1 1 d14 1 a14 1 * $Header: /private/src/postgres/src/backend/utils/init/RCS/miscinit.c,v 1.8 1992/09/05 23:42:29 mao Exp mao $ a35 1 #define DEFAULT_PGHOME "/usr/postgres" d290 1 d293 1 d295 1 a295 1 return (DEFAULT_PGHOME); d305 2 a306 4 if ((p = getenv("PGDATA")) == (char *) NULL) { h = GetPGHome(); sprintf(data, "%s/data", h); p = &data[0]; d309 1 a309 1 return (p); @ 1.8 log @allow location of data/ to be supplied in environment or on command line @ text @d13 1 a13 1 * $Header: /private/mao/postgres/src/utils/init/RCS/miscinit.c,v 1.7 1992/04/03 19:49:30 mao Exp $ d140 6 @ 1.7 log @set UserId the old way when bootstrapping @ text @d13 1 a13 1 * $Header: /private/postgres.d/src/utils/init/RCS/miscinit.c,v 1.6 1992/04/02 19:14:15 mer Exp mao $ d288 16 @ 1.6 log @set UserId correctly (via pg_user) @ text @d13 1 a13 1 * $Header: /users/mer/pg/src/utils/init/RCS/miscinit.c,v 1.5 1991/11/12 20:20:29 mer Exp mer $ d241 1 a241 1 Relation userRel = heap_openr(UserRelationName); d244 12 @ 1.5 log @prototyping changes @ text @d13 1 a13 1 * $Header: /users/mer/postgres/src/utils/init/RCS/miscinit.c,v 1.4 1991/09/09 23:57:48 mao Exp mer $ d26 4 a229 2 * * XXX perform lookup in USER relation d232 4 d239 20 a258 1 UserId = getuid(); @ 1.4 log @add an exported GetPGHome() routine, so that we have a reliable way of figuring out where we belong. @ text @d13 1 a13 1 * $Header: /local/mao/postgres/src/utils/init/RCS/miscinit.c,v 1.3 1991/09/06 12:31:20 hong Exp mao $ a245 1 extern char *getenv(); @ 1.3 log @hashlib.h is now obsoleted. @ text @d13 1 a13 1 * $Header: RCS/miscinit.c,v 1.2 90/10/10 00:42:37 cimarron Exp Locker: hong $ d31 1 d234 18 @ 1.2 log @moved functions around to eliminate linking problem with support/backend. @ text @d13 1 a13 1 * $Header: RCS/miscinit.c,v 1.1 90/10/05 16:01:14 cimarron Exp $ a18 1 #include "tmp/hasht.h" /* for EnableHashTable, etc. */ @ 1.1 log @ Misc initialization code collected from: /users/cimarron/postgres14/src/utils/init/cinit.c /users/cimarron/postgres14/src/utils/init/pdir.c /users/cimarron/postgres14/src/utils/init/pinit.c /users/cimarron/postgres14/src/utils/init/pmod.c /users/cimarron/postgres14/src/utils/init/pusr.c Cim @ text @d13 1 a13 1 * $Header$ d26 72 @