LIBOBJS="$LIBOBJS copydir.$ac_objext"
LIBOBJS="$LIBOBJS gettimeofday.$ac_objext"
LIBOBJS="$LIBOBJS open.$ac_objext"
-LIBOBJS="$LIBOBJS pipe.$ac_objext"
LIBOBJS="$LIBOBJS rand.$ac_objext"
cat >>confdefs.h <<\_ACEOF
dnl Process this file with autoconf to produce a configure script.
-dnl $PostgreSQL: pgsql/configure.in,v 1.345 2004/05/07 00:24:57 tgl Exp $
+dnl $PostgreSQL: pgsql/configure.in,v 1.346 2004/05/11 21:57:13 momjian Exp $
dnl
dnl Developers, please strive to achieve this order:
dnl
AC_LIBOBJ(copydir)
AC_LIBOBJ(gettimeofday)
AC_LIBOBJ(open)
-AC_LIBOBJ(pipe)
AC_LIBOBJ(rand)
AC_DEFINE(USE_PGTZ, 1,
[Define to 1 to use our own timezone library])
# -*-makefile-*-
-# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.181 2004/05/07 00:24:57 tgl Exp $
+# $PostgreSQL: pgsql/src/Makefile.global.in,v 1.182 2004/05/11 21:57:14 momjian Exp $
#------------------------------------------------------------------------------
# All PostgreSQL makefiles include this file and use the variables it sets,
#
# substitute implementations of the C library
-LIBOBJS = @LIBOBJS@ noblock.o path.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
+LIBOBJS = @LIBOBJS@ exec.o noblock.o path.o pipe.o pgsleep.o pgstrcasecmp.o sprompt.o thread.o
ifneq (,$(LIBOBJS))
LIBS += -lpgport
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.382 2004/05/06 19:23:25 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/postmaster/postmaster.c,v 1.383 2004/05/11 21:57:14 momjian Exp $
*
* NOTES
*
/*
* On some systems our dynloader code needs the executable's pathname.
*/
- if (FindExec(pg_pathname, progname, "postgres") < 0)
+ if (find_my_binary(pg_pathname, progname, "postgres") < 0)
ereport(FATAL,
(errmsg("%s: could not locate postgres executable",
progname)));
FILE *fp;
int i;
- if (FindExec(fullprogname, argv[0], "postmaster") < 0)
+ if (find_my_binary(fullprogname, argv[0], "postmaster") < 0)
{
elog(LOG, "could not locate postmaster");
return false;
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.402 2004/05/07 01:53:41 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.403 2004/05/11 21:57:14 momjian Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
* On some systems our dynloader code needs the executable's
* pathname. (If under postmaster, this was done already.)
*/
- if (FindExec(pg_pathname, argv[0], "postgres") < 0)
+ if (find_my_binary(pg_pathname, argv[0], "postgres") < 0)
ereport(FATAL,
(errmsg("%s: could not locate postgres executable",
argv[0])));
# Makefile for utils/init
#
# IDENTIFICATION
-# $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.16 2003/11/29 19:52:01 pgsql Exp $
+# $PostgreSQL: pgsql/src/backend/utils/init/Makefile,v 1.17 2004/05/11 21:57:14 momjian Exp $
#
#-------------------------------------------------------------------------
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = findbe.o globals.o miscinit.o postinit.o
+OBJS = globals.o miscinit.o postinit.o
all: SUBSYS.o
# Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.36 2004/04/26 17:40:48 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/initdb/Makefile,v 1.37 2004/05/11 21:57:14 momjian Exp $
#
#-------------------------------------------------------------------------
top_builddir = ../../..
include $(top_builddir)/src/Makefile.global
-override CPPFLAGS := -DPGBINDIR=\"$(bindir)\" -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
+override CPPFLAGS := -DPGDATADIR=\"$(datadir)\" -DFRONTEND -I$(libpq_srcdir) $(CPPFLAGS)
-OBJS= initdb.o
+OBJS= initdb.o \
+ $(filter exec.o, $(LIBOBJS))
all: submake-libpq submake-libpgport initdb
initdb: $(OBJS) $(libpq_builddir)/libpq.a
$(CC) $(CFLAGS) $(OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+exec.c: % : $(top_srcdir)/src/port/%
+ rm -f $@ && $(LN_S) $< .
+
install: all installdirs
$(INSTALL_PROGRAM) initdb$(X) $(DESTDIR)$(bindir)/initdb$(X)
rm -f $(DESTDIR)$(bindir)/initdb$(X)
clean distclean maintainer-clean:
- rm -f initdb$(X) $(OBJS)
+ rm -f initdb$(X) $(OBJS) exec.c
-# ensure that changes in bindir etc. propagate into object file
+# ensure that changes in datadir propagate into object file
initdb.o: initdb.c $(top_builddir)/src/Makefile.global
*
* template0 is made just by copying the completed template1.
*
- *
- * TODO:
- * - clean up find_postgres code and return values
- *
* Note:
* The program has some memory leakage - it isn't worth cleaning it up.
*
* Portions Copyright (c) 1994, Regents of the University of California
* Portions taken from FreeBSD.
*
- * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.26 2004/05/10 20:51:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/bin/initdb/initdb.c,v 1.27 2004/05/11 21:57:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <dirent.h>
#include <sys/stat.h>
-#include <sys/wait.h>
#include <unistd.h>
#include <locale.h>
#include <signal.h>
* Note that "datadir" is not the directory we're going to initialize,
* it's merely how Autoconf names PREFIX/share.
*/
-char *bindir = PGBINDIR;
char *datadir = PGDATADIR;
/* values to be obtained from arguments */
/* internal vars */
char *progname;
-char *self_path;
char *postgres;
char *encodingid = "0";
char *bki_file;
static const char *backend_options = "-F -O -c search_path=pg_catalog -c exit_on_error=true";
-/* platform specific path stuff */
-#if defined(__CYGWIN__) || defined(WIN32)
-#define EXE ".exe"
-#define DEVNULL "nul"
-#else
-#define EXE ""
-#define DEVNULL "/dev/null"
-#endif
-
-
-/* detected path to postgres and (we assume) friends */
-char *pgpath;
-
-/* forward declare all our functions */
-#ifdef WIN32
-static char *expanded_path(char *);
-#else
-#define expanded_path(x) (x)
-#endif
+/* path to 'initdb' binary directory */
+char bindir[MAXPGPATH];
+char backendbin[MAXPGPATH];
static void *xmalloc(size_t size);
static char *xstrdup(const char *s);
static char **replace_token(char **lines, char *token, char *replacement);
static char **readfile(char *path);
static void writefile(char *path, char **lines);
-static void pclose_check(FILE *stream);
static int mkdir_p(char *path, mode_t omode);
static void exit_nicely(void);
static char *get_id(void);
static bool mkdatadir(char *subdir);
static void set_input(char **dest, char *filename);
static void check_input(char *path);
-static int find_postgres(char *path);
-static int set_paths(void);
static void set_short_version(char *short_version, char *extrapath);
static void set_null_conf(void);
static void test_connections(void);
#define PG_CMD_CLOSE \
do { \
- pclose_check(pg); \
+ if (pclose_check(pg)) \
+ exit_nicely(); \
} while (0)
#define PG_CMD_PUTLINE \
exit_nicely();
}
-/* pclose() plus useful error reporting */
-static void
-pclose_check(FILE *stream)
-{
- int exitstatus;
-
- exitstatus = pclose(stream);
-
- if (exitstatus == 0)
- return; /* all is well */
-
- if (exitstatus == -1)
- {
- /* pclose() itself failed, and hopefully set errno */
- perror("pclose failed");
- }
- else if (WIFEXITED(exitstatus))
- {
- fprintf(stderr, _("%s: child process exited with exit code %d\n"),
- progname, WEXITSTATUS(exitstatus));
- }
- else if (WIFSIGNALED(exitstatus))
- {
- fprintf(stderr, _("%s: child process was terminated by signal %d\n"),
- progname, WTERMSIG(exitstatus));
- }
- else
- {
- fprintf(stderr, _("%s: child process exited with unrecognized status %d\n"),
- progname, exitstatus);
- }
-
- exit_nicely();
-}
-
/* source stolen from FreeBSD /src/bin/mkdir/mkdir.c and adapted */
/*
}
-/*
- * TODO - clean this up and handle the errors properly
- * don't overkill
- */
-#define FIND_SUCCESS 0
-#define FIND_NOT_FOUND 1
-#define FIND_STAT_ERR 2
-#define FIND_NOT_REGFILE 3
-#define FIND_BAD_PERM 4
-#define FIND_EXEC_ERR 5
-#define FIND_WRONG_VERSION 6
-
-/*
- * see if there is a postgres executable in the given path, and giving the
- * right version number
- */
-static int
-find_postgres(char *path)
-{
- char fn[MAXPGPATH];
- char cmd[MAXPGPATH];
- char line[100];
-
-#ifndef WIN32
- int permmask = S_IROTH | S_IXOTH;
-#endif
-
- struct stat statbuf;
- FILE *pgver;
- int plen = strlen(path);
-
- if (plen > 0 && path[plen - 1] != '/')
- snprintf(fn, sizeof(fn), "%s/postgres%s", path, EXE);
- else
- snprintf(fn, sizeof(fn), "%spostgres%s", path, EXE);
-
- if (stat(fn, &statbuf) != 0)
- {
- if (errno == ENOENT)
- return FIND_NOT_FOUND;
- else
- return FIND_STAT_ERR;
- }
- if (!S_ISREG(statbuf.st_mode))
- return FIND_NOT_REGFILE;
-
-#ifndef WIN32
-
- /*
- * Only unix requires this test, on WIN32 an .exe file should be
- * executable
- */
- if ((statbuf.st_mode & permmask) != permmask)
- return FIND_BAD_PERM;
-#endif
-
- snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -V 2>%s", path, DEVNULL);
-
- /* flush output buffers in case popen does not... */
- fflush(stdout);
- fflush(stderr);
-
- if ((pgver = popen(cmd, "r")) == NULL)
- return FIND_EXEC_ERR;
-
- if (fgets(line, sizeof(line), pgver) == NULL)
- perror("fgets failure");
-
- pclose_check(pgver);
-
- if (strcmp(line, PG_VERSIONSTR) != 0)
- return FIND_WRONG_VERSION;
-
- return FIND_SUCCESS;
-}
-
-/*
- * Windows doesn't like relative paths to executables (other things work fine)
- * so we call its builtin function to expand them. Elsewhere this is a NOOP
- */
-#ifdef WIN32
-static char *
-expanded_path(char *path)
-{
- char abspath[MAXPGPATH];
-
- if (_fullpath(abspath, path, sizeof(abspath)) == NULL)
- {
- perror("expanded path");
- return path;
- }
- canonicalize_path(abspath);
- return xstrdup(abspath);
-}
-#endif
-
-/*
- * set the paths pointing to postgres
- *
- * look for it in the same place we found this program, or in the environment
- * path, or in the configured bindir.
- * We do it in this order because during upgrades users might move
- * their trees to backup places, so the hard-wired bindir might be inaccurate.
- *
- * XXX this needs work, as its error handling is vastly inferior to the
- * shell-script version, in particular the case where a postgres executable
- * is failing
- */
-static int
-set_paths(void)
-{
- if (testpath && !self_path)
- {
- char *path,
- *cursor;
- int pathlen,
- i,
- pathsegs;
- char **pathbits;
- char buf[MAXPGPATH];
- struct stat statbuf;
-
- path = xstrdup(getenv("PATH"));
- pathlen = strlen(path);
-
- for (i = 0, pathsegs = 1; i < pathlen; i++)
- {
- if (path[i] == PATHSEP)
- pathsegs++;
- }
-
- pathbits = (char **) xmalloc(pathsegs * sizeof(char *));
- for (i = 0, pathsegs = 0, cursor = path; i <= pathlen; i++)
- {
- if (path[i] == PATHSEP || path[i] == 0)
- {
- path[i] = 0;
- if (strlen(cursor) == 0)
- {
- /* empty path segment means current directory */
- pathbits[pathsegs] = xstrdup(".");
- }
- else
- {
- canonicalize_path(cursor);
- pathbits[pathsegs] = cursor;
- }
- pathsegs++;
- cursor = path + i + 1;
- }
- }
-
- for (i = 0; i < pathsegs; i++)
- {
- snprintf(buf, sizeof(buf), "%s/%s%s", pathbits[i], progname, EXE);
- if (stat(buf, &statbuf) == 0 && S_ISREG(statbuf.st_mode))
- {
- self_path = pathbits[i];
- break;
- }
- }
- }
-
- if (testpath && self_path &&
- (find_postgres(expanded_path(self_path)) == 0))
- {
- /* we found postgres on out own path */
- pgpath = expanded_path(self_path);
- }
- else
- {
- /* look in the hardcoded bindir */
- int res;
- char *cbindir;
-
- cbindir = xstrdup(bindir);
- canonicalize_path(cbindir);
- res = find_postgres(expanded_path(cbindir));
- if (res == 0)
- pgpath = expanded_path(cbindir);
- else
- return 1;
- }
-
- return 0;
-}
-
/*
* write out the PG_VERSION file in the data dir, or its subdirectory
* if extrapath is not NULL
for (i = 0; i < len; i++)
{
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x0 %s "
+ "\"%s\" -boot -x0 %s "
"-c shared_buffers=%d -c max_connections=%d template1 "
"<%s >%s 2>&1",
- pgpath, boot_options,
+ backendbin, boot_options,
conns[i] * 5, conns[i],
DEVNULL, DEVNULL);
status = system(cmd);
for (i = 0; i < len; i++)
{
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x0 %s "
+ "\"%s\" -boot -x0 %s "
"-c shared_buffers=%d -c max_connections=%d template1 "
"<%s >%s 2>&1",
- pgpath, boot_options,
+ backendbin, boot_options,
bufs[i], n_connections,
DEVNULL, DEVNULL);
status = system(cmd);
unsetenv("PGCLIENTENCODING");
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" -boot -x1 %s %s template1",
- pgpath, boot_options, talkargs);
+ "\"%s\" -boot -x1 %s %s template1",
+ backendbin, boot_options, talkargs);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
* We use -N here to avoid backslashing stuff in system_views.sql
*/
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s -N template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s -N template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
* We use -N here to avoid backslashing stuff in information_schema.sql
*/
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s -N template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s -N template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
PG_CMD_CLOSE;
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
fflush(stdout);
snprintf(cmd, sizeof(cmd),
- "\"%s/postgres\" %s template1 >%s",
- pgpath, backend_options,
+ "\"%s\" %s template1 >%s",
+ backendbin, backend_options,
DEVNULL);
PG_CMD_OPEN;
};
int c,
- i;
+ i,
+ ret;
int option_index;
char *short_version;
char *pgdenv; /* PGDATA value got from sent to
* environment */
char *subdirs[] =
{"global", "pg_xlog", "pg_clog", "base", "base/1"};
- char *lastsep;
- char *carg0;
-#if defined(__CYGWIN__) || defined(WIN32)
- char *exe; /* location of exe suffix in progname */
-#endif
-
init_nls();
- /* parse argv[0] - detect explicit path if there was one */
- carg0 = xstrdup(argv[0]);
- canonicalize_path(carg0);
-
- lastsep = strrchr(carg0, '/');
- progname = lastsep ? xstrdup(lastsep + 1) : carg0;
-
-#if defined(__CYGWIN__) || defined(WIN32)
- if (strlen(progname) > 4 &&
- (exe = progname + (strlen(progname) - 4)) &&
- stricmp(exe, EXE) == 0)
- {
- /* strip .exe suffix, regardless of case */
- *exe = '\0';
- }
-#endif
-
- if (lastsep)
- {
- self_path = carg0;
- *lastsep = '\0';
- }
- else
- {
- /* no path known to ourselves from argv[0] */
- self_path = NULL;
- }
+ progname = get_progname(argv[0]);
if (argc > 1)
{
sprintf(pgdenv, "PGDATA=%s", pg_data);
putenv(pgdenv);
- if (set_paths() != 0)
+ if ((ret = find_other_binary(backendbin, argv[0], progname, "postgres",
+ PG_VERSIONSTR)) < 0)
{
- fprintf(stderr,
- _("The program \"postgres\" is needed by %s "
- "but was not found in \n"
- "the directory \"%s\". Check your installation.\n"),
- progname, bindir);
+ if (ret == -1)
+ fprintf(stderr,
+ _("The program \"postgres\" is needed by %s "
+ "but was not found in the same directory as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
+ else
+ fprintf(stderr,
+ _("The program \"postgres\" was found by %s "
+ "but was not the same version as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
exit(1);
}
+ /* store binary directory */
+ strcpy(bindir, backendbin);
+ *last_path_separator(bindir) = '\0';
+
if ((short_version = get_short_version()) == NULL)
{
fprintf(stderr, _("%s: could not determine valid short version string\n"), progname);
"POSTGRES_DESCR=%s\nPOSTGRESQL_CONF_SAMPLE=%s\n"
"PG_HBA_SAMPLE=%s\nPG_IDENT_SAMPLE=%s\n",
PG_VERSION,
- pg_data, datadir, pgpath,
+ pg_data, datadir, bindir,
encoding, encodingid,
username, bki_file,
desc_file, conf_file,
" %s%s%s/postmaster -D %s%s%s\n"
"or\n"
" %s%s%s/pg_ctl -D %s%s%s -l logfile start\n\n"),
- QUOTE_PATH, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
- QUOTE_PATH, pgpath, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
+ QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH,
+ QUOTE_PATH, bindir, QUOTE_PATH, QUOTE_PATH, pg_data, QUOTE_PATH);
return 0;
}
# Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California
#
-# $PostgreSQL: pgsql/src/bin/pg_dump/Makefile,v 1.46 2004/04/30 20:01:39 momjian Exp $
+# $PostgreSQL: pgsql/src/bin/pg_dump/Makefile,v 1.47 2004/05/11 21:57:14 momjian Exp $
#
#-------------------------------------------------------------------------
OBJS= pg_backup_archiver.o pg_backup_db.o pg_backup_custom.o \
pg_backup_files.o pg_backup_null.o pg_backup_tar.o \
dumputils.o
+PG_DUMPALL_OBJS = $(filter exec.o, $(LIBOBJS))
EXTRA_OBJS = $(top_builddir)/src/backend/parser/keywords.o
-override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS) -DBINDIR=\"$(bindir)\"
+override CPPFLAGS := -I$(libpq_srcdir) $(CPPFLAGS)
all: submake-libpq submake-libpgport submake-backend pg_dump pg_restore pg_dumpall
pg_restore: pg_restore.o $(OBJS) $(libpq_builddir)/libpq.a
$(CC) $(CFLAGS) pg_restore.o $(OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
-pg_dumpall: pg_dumpall.o dumputils.o $(libpq_builddir)/libpq.a
- $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+pg_dumpall: pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(libpq_builddir)/libpq.a
+ $(CC) $(CFLAGS) pg_dumpall.o dumputils.o $(PG_DUMPALL_OBJS) $(EXTRA_OBJS) $(libpq) $(LDFLAGS) $(LIBS) -o $@$(X)
+
+exec.c: % : $(top_srcdir)/src/port/%
+ rm -f $@ && $(LN_S) $< .
.PHONY: submake-backend
submake-backend:
rm -f $(addprefix $(DESTDIR)$(bindir)/, pg_dump$(X) pg_restore$(X) pg_dumpall$(X))
clean distclean maintainer-clean:
- rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o
-
-
-# ensure that changes in bindir etc. propagate into object file
-pg_dumpall.o: pg_dumpall.c $(top_builddir)/src/Makefile.global
+ rm -f pg_dump$(X) pg_restore$(X) pg_dumpall$(X) $(OBJS) pg_dump.o common.o pg_dump_sort.o pg_restore.o pg_dumpall.o exec.c
* Portions Copyright (c) 1994, Regents of the University of California
*
*
- * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.30 2004/01/22 19:09:32 tgl Exp $
+ * $PostgreSQL: pgsql/src/bin/pg_dump/pg_dumpall.c,v 1.31 2004/05/11 21:57:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#define _(x) gettext((x))
+/* version string we expect back from postgres */
+#define PG_VERSIONSTR "pg_dump (PostgreSQL) " PG_VERSION "\n"
+
static char *progname;
static PGconn *connectDatabase(const char *dbname, const char *pghost, const char *pgport,
const char *pguser, bool require_password);
static PGresult *executeQuery(PGconn *conn, const char *query);
-static char *findPgDump(const char *argv0);
-char *pgdumploc;
+char pg_dump_bin[MAXPGPATH];
PQExpBuffer pgdumpopts;
bool output_clean = false;
bool skip_acls = false;
bool globals_only = false;
bool schema_only = false;
PGconn *conn;
- int c;
+ int c, ret;
static struct option long_options[] = {
{"data-only", no_argument, NULL, 'a'},
}
}
- pgdumploc = findPgDump(argv[0]);
+ if ((ret = find_other_binary(pg_dump_bin, argv[0], progname, "pg_dump",
+ PG_VERSIONSTR)) < 0)
+ {
+ if (ret == -1)
+ fprintf(stderr,
+ _("The program \"pg_dump\" is needed by %s "
+ "but was not found in the same directory as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
+ else
+ fprintf(stderr,
+ _("The program \"pg_dump\" was found by %s "
+ "but was not the same version as \"%s\".\n"
+ "Check your installation.\n"),
+ progname, progname);
+ exit(1);
+ }
+
pgdumpopts = createPQExpBuffer();
while ((c = getopt_long(argc, argv, "acdDgh:iop:sU:vWx", long_options, &optindex)) != -1)
const char *p;
int ret;
- appendPQExpBuffer(cmd, "%s %s -Fp '", pgdumploc, pgdumpopts->data);
+ appendPQExpBuffer(cmd, "\"%s\" %s -Fp '", pg_dump_bin, pgdumpopts->data);
/* Shell quoting is not quite like SQL quoting, so can't use fmtId */
for (p = dbname; *p; p++)
return res;
}
-
-
-
-/*
- * Find location of pg_dump executable.
- */
-static char *
-findPgDump(const char *argv0)
-{
- char *last;
- PQExpBuffer cmd;
- static char *result = NULL;
-
- if (result)
- return result;
-
- cmd = createPQExpBuffer();
- last = last_path_separator(argv0);
-
- if (!last)
- appendPQExpBuffer(cmd, "pg_dump");
- else
- {
- char *dir = strdup(argv0);
-
- *(dir + (last - argv0)) = '\0';
- appendPQExpBuffer(cmd, "%s/pg_dump", dir);
- }
-
- result = strdup(cmd->data);
-
- appendPQExpBuffer(cmd, " -V >/dev/null 2>&1");
- if (system(cmd->data) == 0)
- goto end;
-
- result = BINDIR "/pg_dump";
- if (system(BINDIR "/pg_dump -V >/dev/null 2>&1") == 0)
- goto end;
-
- fprintf(stderr, _("%s: could not find pg_dump\n"
- "Make sure it is in the path or in the same directory as %s.\n"),
- progname, progname);
- exit(1);
-
-end:
- destroyPQExpBuffer(cmd);
- return result;
-}
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.156 2004/04/12 16:19:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/miscadmin.h,v 1.157 2004/05/11 21:57:15 momjian Exp $
*
* NOTES
* some of the information in this file should be moved to
extern void SetDataDir(const char *dir);
-extern int FindExec(char *full_path, const char *argv0,
- const char *binary_name);
-extern int CheckPathAccess(char *path, char *name, int open_mode);
-
/* in utils/misc/superuser.c */
extern bool superuser(void); /* current user is superuser */
extern bool superuser_arg(AclId userid); /* given user is superuser */
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/port.h,v 1.28 2004/05/07 00:24:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/port.h,v 1.29 2004/05/11 21:57:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
extern void canonicalize_path(char *path);
extern char *get_progname(char *argv0);
+/* Portable way to find binaries */
+extern int find_my_binary(char *full_path, const char *argv0,
+ const char *binary_name);
+extern int find_other_binary(char *retpath, const char *argv0, const char *progname,
+ char const *target, const char *versionstr);
+
+#if defined(__CYGWIN__) || defined(WIN32)
+#define EXE ".exe"
+#define DEVNULL "nul"
+#else
+#define EXE ""
+#define DEVNULL "/dev/null"
+#endif
+
/* Portable delay handling */
extern void pg_usleep(long microsec);
extern int piperead(int s, char* buf, int len);
#define pipewrite(a,b,c) send(a,b,c,0)
#endif
+extern int pclose_check(FILE *stream);
#if defined(__MINGW32__) || defined(__CYGWIN__)
/*
/*-------------------------------------------------------------------------
*
- * findbe.c
+ * exec.c
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/utils/init/findbe.c,v 1.42 2004/03/15 16:18:43 momjian Exp $
+ * $PostgreSQL: pgsql/src/port/exec.c,v 1.1 2004/05/11 21:57:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
+
+#ifndef FRONTEND
#include "postgres.h"
+#else
+#include "postgres_fe.h"
+#endif
#include <grp.h>
#include <pwd.h>
#define S_IXOTH ((S_IXUSR)>>6)
#endif
+#ifndef FRONTEND
+/* We use only 3-parameter elog calls in this file, for simplicity */
+#define log_debug(str, param) elog(DEBUG2, str, param)
+#else
+#define log_debug(str, param) {} /* do nothing */
+#endif
+
+static void win32_make_absolute(char *path);
/*
- * ValidateBinary -- validate "path" as a POSTMASTER/POSTGRES executable file
+ * validate_exec -- validate "path" as an executable file
*
* returns 0 if the file is found and no error is encountered.
* -1 if the regular file "path" does not exist or cannot be executed.
* -2 if the file is otherwise valid but cannot be read.
*/
static int
-ValidateBinary(char *path)
+validate_exec(char *path)
{
struct stat buf;
#ifdef WIN32
/* Win32 requires a .exe suffix for stat() */
- if (strlen(path) >= 4 && strcmp(path + strlen(path) - strlen(".exe"), ".exe") != 0)
+ if (strlen(path) >= strlen(".exe") &&
+ pg_strcasecmp(path + strlen(path) - strlen(".exe"), ".exe") != 0)
{
strcpy(path_exe, path);
strcat(path_exe, ".exe");
*/
if (stat(path, &buf) < 0)
{
- elog(DEBUG3, "could not stat \"%s\": %m", path);
+ log_debug("could not stat \"%s\": %m", path);
return -1;
}
if ((buf.st_mode & S_IFMT) != S_IFREG)
{
- elog(DEBUG3, "\"%s\" is not a regular file", path);
+ log_debug("\"%s\" is not a regular file", path);
return -1;
}
/*
- * Ensure that we are using an authorized backend.
- *
- * XXX I'm open to suggestions here. I would like to enforce ownership
- * of binaries by user "postgres" but people seem to like to run as
- * users other than "postgres"...
+ * Ensure that we are using an authorized executable.
*/
/*
return is_x ? (is_r ? 0 : -2) : -1;
#else
euid = geteuid();
+
+ /* If owned by us, just check owner bits */
if (euid == buf.st_uid)
{
is_r = buf.st_mode & S_IRUSR;
is_x = buf.st_mode & S_IXUSR;
if (!(is_r && is_x))
- elog(DEBUG3, "\"%s\" is not user read/execute", path);
+ log_debug("\"%s\" is not user read/execute", path);
return is_x ? (is_r ? 0 : -2) : -1;
}
- pwp = getpwuid(euid);
+
+ /* OK, check group bits */
+
+ pwp = getpwuid(euid); /* not thread-safe */
if (pwp)
{
- if (pwp->pw_gid == buf.st_gid)
+ if (pwp->pw_gid == buf.st_gid) /* my primary group? */
++in_grp;
else if (pwp->pw_name &&
- (gp = getgrgid(buf.st_gid)) != NULL &&
+ (gp = getgrgid(buf.st_gid)) != NULL && /* not thread-safe */
gp->gr_mem != NULL)
- {
+ { /* try list of member groups */
for (i = 0; gp->gr_mem[i]; ++i)
{
if (!strcmp(gp->gr_mem[i], pwp->pw_name))
is_r = buf.st_mode & S_IRGRP;
is_x = buf.st_mode & S_IXGRP;
if (!(is_r && is_x))
- elog(DEBUG3, "\"%s\" is not group read/execute", path);
+ log_debug("\"%s\" is not group read/execute", path);
return is_x ? (is_r ? 0 : -2) : -1;
}
}
+
+ /* Check "other" bits */
is_r = buf.st_mode & S_IROTH;
is_x = buf.st_mode & S_IXOTH;
if (!(is_r && is_x))
- elog(DEBUG3, "\"%s\" is not other read/execute", path);
+ log_debug("\"%s\" is not other read/execute", path);
return is_x ? (is_r ? 0 : -2) : -1;
+
#endif
}
/*
- * FindExec -- find an absolute path to a valid backend executable
+ * find_my_binary -- find an absolute path to a valid executable
*
* The reason we have to work so hard to find an absolute path is that
* on some platforms we can't do dynamic loading unless we know the
* executable's location. Also, we need a full path not a relative
* path because we will later change working directory.
+ *
+ * This function is not thread-safe because of it calls validate_exec(),
+ * which calls getgrgid(). This function should be used only in
+ * non-threaded binaries, not in library routines.
*/
int
-FindExec(char *full_path, const char *argv0, const char *binary_name)
+find_my_binary(char *full_path, const char *argv0, const char *binary_name)
{
char buf[MAXPGPATH + 2];
char *p;
*endp;
/*
- * for the postmaster: First try: use the binary that's located in the
- * same directory as the postmaster, if it was invoked with an
- * explicit path. Presumably the user used an explicit path because it
+ * First try: use the binary that's located in the
+ * same directory if it was invoked with an explicit path.
+ * Presumably the user used an explicit path because it
* wasn't in PATH, and we don't want to use incompatible executables.
*
* This has the neat property that it works for installed binaries, old
- * source trees (obj/support/post{master,gres}) and new marc source
+ * source trees (obj/support/post{master,gres}) and new source
* trees (obj/post{master,gres}) because they all put the two binaries
* in the same place.
*
strcat(buf, argv0);
p = last_path_separator(buf);
strcpy(++p, binary_name);
- if (ValidateBinary(buf) == 0)
+ if (validate_exec(buf) == 0)
{
strncpy(full_path, buf, MAXPGPATH);
- elog(DEBUG2, "found \"%s\" using argv[0]", full_path);
+ win32_make_absolute(full_path);
+ log_debug("found \"%s\" using argv[0]", full_path);
return 0;
}
- elog(DEBUG2, "invalid binary \"%s\"", buf);
+ log_debug("invalid binary \"%s\"", buf);
return -1;
}
*/
if ((p = getenv("PATH")) && *p)
{
- elog(DEBUG2, "searching PATH for executable");
+ log_debug("searching PATH for executable%s", "");
path = strdup(p); /* make a modifiable copy */
for (startp = path, endp = strchr(path, PATHSEP);
startp && *startp;
strcat(buf, startp);
strcat(buf, "/");
strcat(buf, binary_name);
- switch (ValidateBinary(buf))
+ switch (validate_exec(buf))
{
case 0: /* found ok */
strncpy(full_path, buf, MAXPGPATH);
- elog(DEBUG2, "found \"%s\" using PATH", full_path);
+ win32_make_absolute(full_path);
+ log_debug("found \"%s\" using PATH", full_path);
free(path);
return 0;
case -1: /* wasn't even a candidate, keep looking */
break;
case -2: /* found but disqualified */
- elog(DEBUG2, "could not read binary \"%s\"", buf);
+ log_debug("could not read binary \"%s\"", buf);
free(path);
return -1;
}
free(path);
}
- elog(DEBUG2, "could not find a \"%s\" to execute", binary_name);
+ log_debug("could not find a \"%s\" to execute", binary_name);
return -1;
}
+
+
+/*
+ * Find our binary directory, then make sure the "target" executable
+ * is the proper version.
+ */
+int find_other_binary(char *retpath, const char *argv0, const char *progname,
+ char const *target, const char *versionstr)
+{
+ char cmd[MAXPGPATH];
+ char line[100];
+ FILE *pgver;
+
+ if (find_my_binary(retpath, argv0, progname) < 0)
+ return -1;
+
+ /* Trim off program name and keep just directory */
+ *last_path_separator(retpath) = '\0';
+
+ snprintf(retpath + strlen(retpath), MAXPGPATH - strlen(retpath),
+ "/%s%s", target, EXE);
+
+ if (validate_exec(retpath))
+ return -1;
+
+ snprintf(cmd, sizeof(cmd), "\"%s\" -V 2>%s", retpath, DEVNULL);
+
+ /* flush output buffers in case popen does not... */
+ fflush(stdout);
+ fflush(stderr);
+
+ if ((pgver = popen(cmd, "r")) == NULL)
+ return -1;
+
+ if (fgets(line, sizeof(line), pgver) == NULL)
+ perror("fgets failure");
+
+ if (pclose_check(pgver))
+ return -1;
+
+ if (strcmp(line, versionstr) != 0)
+ return -2;
+
+ return 0;
+}
+
+
+/*
+ * Windows doesn't like relative paths to executables (other things work fine)
+ * so we call its builtin function to expand them. Elsewhere this is a NOOP
+ *
+ * Returns malloc'ed memory.
+ */
+static void
+win32_make_absolute(char *path)
+{
+#ifdef WIN32
+ char abspath[MAXPGPATH];
+
+ if (_fullpath(abspath, path, MAXPGPATH) == NULL)
+ {
+ log_debug("Win32 path expansion failed: %s", strerror());
+ return path;
+ }
+ canonicalize_path(abspath);
+
+ StrNCpy(path, abspath, MAXPGPATH);
+#endif
+ return;
+}
+
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/path.c,v 1.5 2004/03/09 04:49:02 momjian Exp $
+ * $PostgreSQL: pgsql/src/port/path.c,v 1.6 2004/05/11 21:57:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
else
return last_path_separator(argv0) + 1;
}
+
* must be replaced with recv/send.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/pipe.c,v 1.2 2004/04/19 17:42:59 momjian Exp $
+ * $PostgreSQL: pgsql/src/port/pipe.c,v 1.3 2004/05/11 21:57:15 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
+#include <sys/wait.h>
+
+#define _(x) gettext((x))
+
+#ifdef WIN32
int
pgpipe(int handles[2])
{
ret = 0;
return ret;
}
+#endif
+
+/*
+ * pclose() plus useful error reporting
+ * Is this necessary? bjm 2004-05-11
+ */
+int
+pclose_check(FILE *stream)
+{
+ int exitstatus;
+
+ exitstatus = pclose(stream);
+
+ if (exitstatus == 0)
+ return 0; /* all is well */
+
+ if (exitstatus == -1)
+ {
+ /* pclose() itself failed, and hopefully set errno */
+ perror("pclose failed");
+ }
+ else if (WIFEXITED(exitstatus))
+ {
+ fprintf(stderr, _("child process exited with exit code %d\n"),
+ WEXITSTATUS(exitstatus));
+ }
+ else if (WIFSIGNALED(exitstatus))
+ {
+ fprintf(stderr, _("child process was terminated by signal %d\n"),
+ WTERMSIG(exitstatus));
+ }
+ else
+ {
+ fprintf(stderr, _("child process exited with unrecognized status %d\n"),
+ exitstatus);
+ }
+
+ return -1;
+}