aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/init/magic.c
diff options
context:
space:
mode:
authorMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
committerMarc G. Fournier <scrappy@hub.org>1996-07-09 06:22:35 +0000
commitd31084e9d1118b25fd16580d9d8c2924b5740dff (patch)
tree3179e66307d54df9c7b966543550e601eb55e668 /src/backend/utils/init/magic.c
downloadpostgresql-PG95-1_01.tar.gz
postgresql-PG95-1_01.zip
Postgres95 1.01 Distribution - Virgin SourcesPG95-1_01
Diffstat (limited to 'src/backend/utils/init/magic.c')
-rw-r--r--src/backend/utils/init/magic.c167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/backend/utils/init/magic.c b/src/backend/utils/init/magic.c
new file mode 100644
index 00000000000..8e93ff51f5e
--- /dev/null
+++ b/src/backend/utils/init/magic.c
@@ -0,0 +1,167 @@
+/*-------------------------------------------------------------------------
+ *
+ * magic.c--
+ * magic number management routines
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ * $Header: /cvsroot/pgsql/src/backend/utils/init/Attic/magic.c,v 1.1.1.1 1996/07/09 06:22:09 scrappy Exp $
+ *
+ * NOTES
+ * XXX eventually, should be able to handle version identifiers
+ * of length != 4.
+ *
+ * STANDALONE CODE - do not use error routines as this code is linked with
+ * stuff that does not cinterface.a
+ *-------------------------------------------------------------------------
+ */
+#include <sys/file.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "postgres.h"
+
+#include "utils/elog.h"
+#include "miscadmin.h" /* for global decls */
+
+#include "storage/fd.h" /* for O_ */
+
+static char Pg_verfile[] = PG_VERFILE;
+
+
+/*
+ * private function prototypes
+ */
+static void PathSetVersionFilePath(char path[], char filepathbuf[]);
+
+/*
+ * DatabaseMetaGunkIsConsistent
+ *
+ * Returns 1 iff all version numbers and ownerships are consistent.
+ *
+ * Note that we have to go through the whole rigmarole of generating the path
+ * and checking the existence of the database whether Noversion is set or not.
+ */
+int
+DatabaseMetaGunkIsConsistent(char *database, char *path)
+{
+ int isValid;
+#ifndef WIN32
+ struct stat statbuf;
+#else
+ struct _stat statbuf;
+#endif
+
+ /* XXX We haven't changed PG_VERSION since 1.1! */
+#ifndef WIN32
+ isValid = ValidPgVersion(DataDir);
+ sprintf(path, "%s/base/%s", DataDir, database);
+ isValid = ValidPgVersion(path) || isValid;
+#endif /* WIN32 */
+
+ if (stat(path, &statbuf) < 0)
+ elog(FATAL, "database %s does not exist, bailing out...",
+ database);
+
+ return(isValid);
+}
+
+
+/*
+ * ValidPgVersion - verifies the consistency of the database
+ *
+ * Returns 1 iff the catalog version number (from the version number file
+ * in the directory specified in "path") is consistent with the backend
+ * version number.
+ */
+int
+ValidPgVersion(char *path)
+{
+ int fd;
+ char version[4], buf[MAXPGPATH+1];
+#ifndef WIN32
+ struct stat statbuf;
+#else
+ struct _stat statbuf;
+#endif
+ u_short my_euid = geteuid();
+
+ PathSetVersionFilePath(path, buf);
+
+ if (stat(buf, &statbuf) >= 0) {
+ if (statbuf.st_uid != my_euid && my_euid != 0)
+ elog(FATAL,
+ "process userid (%d) != database owner (%d)",
+ my_euid, statbuf.st_uid);
+ } else
+ return(0);
+
+ if ((fd = open(buf, O_RDONLY, 0)) < 0) {
+ if (!Noversion)
+ elog(DEBUG, "ValidPgVersion: %s: %m", buf);
+ return(0);
+ }
+
+ if (read(fd, version, 4) < 4 ||
+ !isascii(version[0]) || !isdigit(version[0]) ||
+ version[1] != '.' ||
+ !isascii(version[2]) || !isdigit(version[2]) ||
+ version[3] != '\n')
+ elog(FATAL, "ValidPgVersion: %s: bad format", buf);
+ if (version[2] != '0' + PG_VERSION ||
+ version[0] != '0' + PG_RELEASE) {
+ if (!Noversion)
+ elog(DEBUG,
+ "ValidPgVersion: should be %d.%d not %c.%c",
+ PG_RELEASE, PG_VERSION, version[0], version[2]);
+ close(fd);
+ return(0);
+ }
+ close(fd);
+ return(1);
+}
+
+
+/*
+ * SetPgVersion - writes the version to a database directory
+ */
+void
+SetPgVersion(char *path)
+{
+ int fd;
+ char version[4], buf[MAXPGPATH+1];
+
+ PathSetVersionFilePath(path, buf);
+
+ if ((fd = open(buf, O_WRONLY|O_CREAT|O_EXCL, 0666)) < 0)
+ elog(FATAL, "SetPgVersion: %s: %m", buf);
+
+ version[0] = '0' + PG_RELEASE;
+ version[1] = '.';
+ version[2] = '0' + PG_VERSION;
+ version[3] = '\n';
+ if (write(fd, version, 4) != 4)
+ elog(WARN, "SetPgVersion: %s: %m", buf);
+
+ close(fd);
+}
+
+
+/*
+ * PathSetVersionFilePath
+ *
+ * Destructively change "filepathbuf" to contain the concatenation of "path"
+ * and the name of the version file name.
+ */
+static void
+PathSetVersionFilePath(char *path, char *filepathbuf)
+{
+ if (strlen(path) > (MAXPGPATH - sizeof(Pg_verfile) - 1))
+ elog(FATAL, "PathSetVersionFilePath: %s: path too long");
+ (void) sprintf(filepathbuf, "%s%c%s", path, SEP_CHAR, Pg_verfile);
+}