From bf80f41ec1b8b7fb16cf3ac695b2e1436ba1e619 Mon Sep 17 00:00:00 2001 From: Bryan Henderson Date: Mon, 11 Nov 1996 13:51:57 +0000 Subject: [PATCH] Add utils directory for cross-subsystem tools to keep make files from having to be sleazy and reach into other subsystems' directories. First entry in this directory is the PG_VERSION file interface, which must be used by the backend and also the pg_version program (which is used by initdb). --- src/Makefile | 3 +- src/utils/Makefile | 29 +++++++++ src/utils/README | 6 ++ src/utils/version.c | 146 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/utils/Makefile create mode 100644 src/utils/README create mode 100644 src/utils/version.c diff --git a/src/Makefile b/src/Makefile index e1cfcd076f..66ddf2e2bf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,7 +7,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/Makefile,v 1.9 1996/10/21 06:56:55 bryanh Exp $ +# $Header: /cvsroot/pgsql/src/Makefile,v 1.10 1996/11/11 13:51:20 bryanh Exp $ # # NOTES # objdir - location of the objects and generated files (eg. obj) @@ -31,6 +31,7 @@ XARGS = xargs you can build Postgres. ;\ false ;\ fi + $(MAKE) -C utils $@ $(MAKE) -C backend $@ $(MAKE) -C libpq $@ ifeq ($(HAVE_Cplusplus), true) diff --git a/src/utils/Makefile b/src/utils/Makefile new file mode 100644 index 0000000000..45ff0cc34a --- /dev/null +++ b/src/utils/Makefile @@ -0,0 +1,29 @@ +#------------------------------------------------------------------------- +# +# Makefile-- +# Makefile for utils +# +# IDENTIFICATION +# $Header: /cvsroot/pgsql/src/utils/Attic/Makefile,v 1.1 1996/11/11 13:51:55 bryanh Exp $ +# +#------------------------------------------------------------------------- + +SRCDIR = .. +include ../Makefile.global + +INCLUDE_OPT = -I../include + +CFLAGS+=$(INCLUDE_OPT) + +all: version.o + +depend dep: + $(CC) -MM $(INCLUDE_OPT) *.c >depend + +clean: + rm -f version.o + +ifeq (depend,$(wildcard depend)) +include depend +endif + diff --git a/src/utils/README b/src/utils/README new file mode 100644 index 0000000000..c7fb0149b3 --- /dev/null +++ b/src/utils/README @@ -0,0 +1,6 @@ +The utils directory contains components that are used by multiple subsystems +in the Postgres source tree. We don't want subsystems reaching into other +subsystems' directories and messing with the modularity of the system, so +we gather any cross-subsystem utilities here. + +In particular, programs that form an interface between subsystems go here. diff --git a/src/utils/version.c b/src/utils/version.c new file mode 100644 index 0000000000..28809c3727 --- /dev/null +++ b/src/utils/version.c @@ -0,0 +1,146 @@ +/*------------------------------------------------------------------------- + * + * version.c-- + * Routines to handle Postgres version number. + * + * Copyright (c) 1994, Regents of the University of California + * + * + * IDENTIFICATION + * $Header: /cvsroot/pgsql/src/utils/Attic/version.c,v 1.1 1996/11/11 13:51:57 bryanh 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 +#include +#include +#include +#include +#include +#include + +#include "postgres.h" + +#include "storage/fd.h" /* for O_ */ + +#include "version.h" + + +static void +PathSetVersionFilePath(const char *path, char *filepathbuf) { +/*---------------------------------------------------------------------------- + PathSetVersionFilePath + + Destructively change "filepathbuf" to contain the concatenation of "path" + and the name of the version file name. +----------------------------------------------------------------------------*/ + if (strlen(path) > (MAXPGPATH - sizeof(PG_VERFILE) - 1)) + *filepathbuf = '\0'; + else + sprintf(filepathbuf, "%s%c%s", path, SEP_CHAR, PG_VERFILE); +} + + + +void +ValidatePgVersion(const char *path, char **reason_p) { +/*---------------------------------------------------------------------------- + Determine whether the PG_VERSION file in directory indicates + a data version compatible with the version of this program. + + If compatible, return <*reason_p> == NULL. Otherwise, malloc space, + fill it with a text string explaining how it isn't compatible (or why + we can't tell), and return a pointer to that space as <*reason_p>. +-----------------------------------------------------------------------------*/ + int fd; + char version[4]; + char full_path[MAXPGPATH+1]; +#ifndef WIN32 + struct stat statbuf; +#else + struct _stat statbuf; +#endif + PathSetVersionFilePath(path, full_path); + + if (stat(full_path, &statbuf) < 0) { + *reason_p = malloc(200); + sprintf(*reason_p, "File '%s' does not exist.", full_path); + } else { + fd = open(full_path, O_RDONLY, 0); + if (fd < 0) { + *reason_p = malloc(200); + sprintf(*reason_p, "Unable to open file '%s'. Errno = %s (%d).", + full_path, strerror(errno), errno); + } else { + if (read(fd, version, 4) < 4 || + !isascii(version[0]) || !isdigit(version[0]) || + version[1] != '.' || + !isascii(version[2]) || !isdigit(version[2]) || + version[3] != '\n') { + + *reason_p = malloc(200); + sprintf(*reason_p, "File '%s' does not have a valid format " + "for a PG_VERSION file.", full_path); + } else { + if (version[2] != '0' + PG_VERSION || + version[0] != '0' + PG_RELEASE) { + *reason_p = malloc(200); + sprintf(*reason_p, + "Version number in file '%s' should be %d.%d, " + "not %c.%c.", + full_path, + PG_RELEASE, PG_VERSION, version[0], version[2]); + } else *reason_p = NULL; + } + close(fd); + } + } +} + + + +void +SetPgVersion(const char *path, char **reason_p) { +/*--------------------------------------------------------------------------- + Create the PG_VERSION file in the directory . + + If we fail, allocate storage, fill it with a text string explaining why, + and return a pointer to that storage as <*reason_p>. If we succeed, + return *reason_p = NULL. +---------------------------------------------------------------------------*/ + int fd; + char version[4]; + char full_path[MAXPGPATH+1]; + + PathSetVersionFilePath(path, full_path); + + fd = open(full_path, O_WRONLY|O_CREAT|O_EXCL, 0666); + if (fd < 0) { + *reason_p = malloc(100 + strlen(full_path)); + sprintf(*reason_p, + "Unable to create file '%s', errno from open(): %s (%d).", + full_path, strerror(errno), errno); + } else { + int rc; /* return code from some function we call */ + + version[0] = '0' + PG_RELEASE; + version[1] = '.'; + version[2] = '0' + PG_VERSION; + version[3] = '\n'; + rc = write(fd, version, 4); + if (rc != 4) { + *reason_p = malloc(100 + strlen(full_path)); + sprintf(*reason_p, + "Failed to write to file '%s', after it was already " + "open. Errno from write(): %s (%d)", + full_path, strerror(errno), errno); + } else *reason_p = NULL; + close(fd); + } +}