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).
This commit is contained in:
Bryan Henderson 1996-11-11 13:51:57 +00:00
parent 6f708e42d1
commit bf80f41ec1
4 changed files with 183 additions and 1 deletions

View File

@ -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)

29
src/utils/Makefile Normal file
View File

@ -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

6
src/utils/README Normal file
View File

@ -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.

146
src/utils/version.c Normal file
View File

@ -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 <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#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 <path> 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 <path>.
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);
}
}