mirror of https://github.com/postgres/postgres
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).REL2_0B
parent
6f708e42d1
commit
bf80f41ec1
@ -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 |
||||
|
@ -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. |
@ -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); |
||||
} |
||||
} |
Loading…
Reference in new issue