From 3280cba2aca54773f6881ee15b5242f117b2860e Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Sat, 28 Oct 2000 22:14:14 +0000 Subject: [PATCH] Make initdb safe against using a) mismatching backend program, by checking --version output b) mismatching bki files, by putting a version-identifying comment atop those files. --- src/backend/catalog/Makefile | 6 +-- src/backend/catalog/genbki.sh | 31 +++++++++----- src/bin/initdb/initdb.sh | 77 +++++++++++++++++++++++------------ 3 files changed, 75 insertions(+), 39 deletions(-) diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile index e17a37388c..e004eea5ee 100644 --- a/src/backend/catalog/Makefile +++ b/src/backend/catalog/Makefile @@ -2,7 +2,7 @@ # # Makefile for catalog # -# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.31 2000/10/24 01:38:23 tgl Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.32 2000/10/28 22:14:14 petere Exp $ # #------------------------------------------------------------------------- @@ -39,11 +39,11 @@ pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include) global.bki global.description: genbki.sh $(GLOBAL_BKI_SRCS) $(top_srcdir)/src/include/catalog/indexing.h \ $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h - CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o global $(pg_includes) $(GLOBAL_BKI_SRCS) + CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o global $(pg_includes) $(GLOBAL_BKI_SRCS) --set-version=$(VERSION) template1.bki template1.description: genbki.sh $(TEMPLATE1_BKI_SRCS) \ $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h - CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o template1 $(pg_includes) $(TEMPLATE1_BKI_SRCS) + CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o template1 $(pg_includes) $(TEMPLATE1_BKI_SRCS) --set-version=$(VERSION) .PHONY: install-bki install-bki: $(BKIFILES) installdirs diff --git a/src/backend/catalog/genbki.sh b/src/backend/catalog/genbki.sh index bcd62ba0af..e9400f4aec 100644 --- a/src/backend/catalog/genbki.sh +++ b/src/backend/catalog/genbki.sh @@ -10,7 +10,7 @@ # # # IDENTIFICATION -# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.17 2000/10/20 21:03:42 petere Exp $ +# $Header: /cvsroot/pgsql/src/backend/catalog/Attic/genbki.sh,v 1.18 2000/10/28 22:14:14 petere Exp $ # # NOTES # non-essential whitespace is removed from the generated file. @@ -28,6 +28,7 @@ BKIOPTS= INCLUDE_DIRS= OUTPUT_PREFIX= INFILES= +major_version= # # Process command line switches. @@ -54,15 +55,20 @@ do -o*) OUTPUT_PREFIX=`echo $1 | sed -e 's/^-o//'` ;; + --set-version=*) + arg=`expr x"$1" : x"--set-version=\(.*\)"` + major_version=`expr x"$arg" : x'\([0-9][0-9]*\.[0-9][0-9]*\)'` + ;; --help) echo "$CMDNAME generates system catalog bootstrapping files." echo echo "Usage:" - echo " $CMDNAME [ -D define [...] ] [ -I dir ] [ -o prefix ]" + echo " $CMDNAME [ -D define [...] ] [ -I dir ] --set-version=VERSION -o prefix files..." echo echo "Options:" echo " -I path to postgres_ext.h and config.h files" echo " -o prefix of output files" + echo " --set-version PostgreSQL version number for initdb cross-check" echo echo "The environment variables CPP and AWK determine which C" echo "preprocessor and Awk program to use. The defaults are" @@ -97,6 +103,10 @@ if [ x"$INCLUDE_DIRS" = x"" ] ; then exit 1 fi +if [ x"$major_version" = x"" ] ; then + echo "$CMDNAME: invalid or no version number specified" 1>&2 + exit 1 +fi if [ x"$TMPDIR" = x"" ] ; then TMPDIR=/tmp @@ -105,12 +115,7 @@ fi TMPFILE="$TMPDIR/genbkitmp.c" -trap "rm -f $TMPFILE" 0 1 2 3 15 - - -# clear output files -> ${OUTPUT_PREFIX}.bki -> ${OUTPUT_PREFIX}.description +trap "rm -f $TMPFILE ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.description.$$" 0 1 2 3 15 # Get NAMEDATALEN from postgres_ext.h @@ -136,6 +141,8 @@ done INDEXMAXKEYS2=`expr $INDEXMAXKEYS '*' 2` || exit INDEXMAXKEYS4=`expr $INDEXMAXKEYS '*' 4` || exit +touch ${OUTPUT_PREFIX}.description.$$ + # ---------------- # strip comments and trash from .h before we generate # the .bki file... @@ -360,11 +367,15 @@ END { reln_open = 0; } } -' "descriptionfile=${OUTPUT_PREFIX}.description" > $TMPFILE || exit +' "descriptionfile=${OUTPUT_PREFIX}.description.$$" > $TMPFILE || exit + +echo "# PostgreSQL $major_version" >${OUTPUT_PREFIX}.bki.$$ $CPP $BKIOPTS $TMPFILE | \ sed -e '/^[ ]*$/d' \ - -e 's/[ ][ ]*/ /g' > ${OUTPUT_PREFIX}.bki || exit + -e 's/[ ][ ]*/ /g' >>${OUTPUT_PREFIX}.bki.$$ || exit +mv ${OUTPUT_PREFIX}.bki.$$ ${OUTPUT_PREFIX}.bki || exit +mv ${OUTPUT_PREFIX}.description.$$ ${OUTPUT_PREFIX}.description || exit exit 0 diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index fc5e8f0423..587c30ecc9 100644 --- a/src/bin/initdb/initdb.sh +++ b/src/bin/initdb/initdb.sh @@ -1,17 +1,17 @@ #! /bin/sh #------------------------------------------------------------------------- # -# initdb creates (initializes) a Postgres database cluster (site, +# initdb creates (initializes) a PostgreSQL database cluster (site, # instance, installation, whatever). A database cluster is a -# collection of Postgres databases all managed by the same postmaster. +# collection of PostgreSQL databases all managed by the same postmaster. # # To create the database cluster, we create the directory that contains # all its data, create the files that hold the global tables, create # a few other control files for it, and create one database: the # template database. # -# The template database is an ordinary Postgres database. Its data -# never changes, though. It exists to make it easy for Postgres to +# The template database is an ordinary PostgreSQL database. Its data +# never changes, though. It exists to make it easy for PostgreSQL to # create other databases -- it just copies. # # Optionally, we can skip creating the complete database cluster and @@ -23,7 +23,7 @@ # # Copyright (c) 1994, Regents of the University of California # -# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.106 2000/10/22 17:55:45 pjw Exp $ +# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.107 2000/10/28 22:14:14 petere Exp $ # #------------------------------------------------------------------------- @@ -85,7 +85,7 @@ fi if echo "$0" | grep '/' > /dev/null 2>&1 then # explicit dir name given - PGPATH=`echo $0 | sed 's,/[^/]*$,,'` # (dirname command is not portable) + self_path=`echo $0 | sed 's,/[^/]*$,,'` # (dirname command is not portable) else # look for it in PATH ('which' command is not portable) for dir in `echo "$PATH" | sed 's/:/ /g'` @@ -94,36 +94,52 @@ else [ -z "$dir" ] && dir='.' if [ -f "$dir/$CMDNAME" ] then - PGPATH="$dir" + self_path="$dir" break fi done fi -if [ x"$PGPATH" = x"" ] ; then - PGPATH=$bindir + +# Check for right version of backend. First we check for an +# executable in the same directory is this initdb script (presuming +# the above code worked). Then we fall back to the hard-wired bindir. +# We do it in this order because during upgrades users might move +# their trees to backup places, so $bindir might be inaccurate. + +if [ x"$self_path" != x"" ] \ + && [ -x "$self_path/postgres" ] \ + && [ x"`$self_path/postgres --version 2>/dev/null`" == x"postgres (PostgreSQL) $VERSION" ] +then + PGPATH=$self_path +elif [ -x "$bindir/postgres" ]; then + if [ x"`$bindir/postgres --version 2>/dev/null`" == x"postgres (PostgreSQL) $VERSION" ] + then + PGPATH=$bindir + else + echo "The program '$bindir/postgres' needed by $CMDNAME does not belong to" + echo "PostgreSQL version $VERSION. Check your installation." + exit 1 + fi +else + echo "The program 'postgres' is needed by $CMDNAME but was not found in" + echo "the directory '$bindir'. Check your installation." + exit 1 fi -# Check if needed programs actually exist in path -for prog in postgres pg_id -do - if [ ! -x "$PGPATH/$prog" ] - then - echo "The program \`$prog' needed by $CMDNAME could not be found. It was" - echo "expected at:" - echo " $PGPATH/$prog" - echo "If this is not the correct directory, please start $CMDNAME" - echo "with a full search path. Otherwise make sure that the program" - echo "was installed successfully." - exit 1 - fi -done + +# Now we can assume that 'pg_id' belongs to the same version as the +# verified 'postgres' in the same directory. +if [ ! -x "$PGPATH/pg_id" ]; then + echo "The program 'pg_id' is needed by $CMDNAME but was not found in" + echo "the directory '$PGPATH'. Check your installation." + exit 1 +fi -# Gotta wait for pg_id existence check above EffectiveUser=`$PGPATH/pg_id -n -u` if [ -z "$EffectiveUser" ]; then - echo "Could not determine current user name. You are really hosed." + echo "$CMDNAME: could not determine current user name" exit 1 fi @@ -275,7 +291,7 @@ fi if [ "$MULTIBYTE" ] then - MULTIBYTEID=`$PGPATH/pg_encoding $MULTIBYTE 2> /dev/null` + MULTIBYTEID=`$PGPATH/pg_encoding $MULTIBYTE` if [ "$?" -ne 0 ] then echo "$CMDNAME: pg_encoding failed" @@ -354,6 +370,15 @@ do fi done +for file in "$TEMPLATE1_BKI" "$GLOBAL_BKI"; do + if [ x"`sed 1q $file`" != x"# PostgreSQL $short_version" ]; then + echo "The input file '$file' needed by $CMDNAME does not" + echo "belong to PostgreSQL $VERSION. Check your installation or specify the" + echo "correct path using the -L option." + exit 1 + fi +done + trap 'echo "Caught signal." ; exit_nicely' 1 2 3 15 -- GitLab