From cff7617b129d458bf77f99e96ad1248d20c6e6d4 Mon Sep 17 00:00:00 2001 From: Tatsuo Ishii Date: Mon, 14 Feb 2005 14:52:21 +0000 Subject: [PATCH] pgpool 2.5.1b1 --- AUTHORS | 3 + COPYING | 12 + ChangeLog | 170 + INSTALL | 1 + Makefile.am | 14 + Makefile.in | 592 ++++ NEWS | 390 +++ README | 584 ++++ README.euc_jp | 801 +++++ TODO | 146 + aclocal.m4 | 1077 +++++++ child.c | 1006 ++++++ config.h.in | 153 + configure | 6713 ++++++++++++++++++++++++++++++++++++++++ configure.in | 56 + depcomp | 522 ++++ install-sh | 251 ++ main.c | 935 ++++++ missing | 360 +++ mkinstalldirs | 40 + pgpool.conf.sample | 102 + pool.h | 315 ++ pool_auth.c | 920 ++++++ pool_config.c | 2175 +++++++++++++ pool_config.l | 638 ++++ pool_connection_pool.c | 453 +++ pool_error.c | 144 + pool_params.c | 161 + pool_process_query.c | 2212 +++++++++++++ pool_signal.c | 158 + pool_signal.h | 58 + pool_stream.c | 600 ++++ version.h | 1 + 33 files changed, 21763 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 README.euc_jp create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100644 child.c create mode 100644 config.h.in create mode 100755 configure create mode 100644 configure.in create mode 100755 depcomp create mode 100755 install-sh create mode 100644 main.c create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 pgpool.conf.sample create mode 100644 pool.h create mode 100644 pool_auth.c create mode 100644 pool_config.c create mode 100644 pool_config.l create mode 100644 pool_connection_pool.c create mode 100644 pool_error.c create mode 100644 pool_params.c create mode 100644 pool_process_query.c create mode 100644 pool_signal.c create mode 100644 pool_signal.h create mode 100644 pool_stream.c create mode 100644 version.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..90bf5e1 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Authors of pgpool + +pgpool was written by Tatsuo Ishii diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..5ad8d3f --- /dev/null +++ b/COPYING @@ -0,0 +1,12 @@ +Copyright (c) 2003 Tatsuo Ishii + +Permission to use, copy, modify, and distribute this software and +its documentation for any purpose and without fee is hereby +granted, provided that the above copyright notice appear in all +copies and that both that copyright notice and this permission +notice appear in supporting documentation, and that the name of the +author not be used in advertising or publicity pertaining to +distribution of the software without specific, written prior +permission. The author makes no representations about the +suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..59f54bb --- /dev/null +++ b/ChangeLog @@ -0,0 +1,170 @@ +2005-02-14 + * version 2.5.1 + * fix bug in heal checking + - sometimes health checking period drifts + - if health checking is intrrupted by SIGCHILD (this could + happen, for exmaple, if child_life_time expires), unwanted + failover happens + * accept fast/immediate shutdown request while blocking in smart + shutdown + * use asprintf to avoid log output confusion (thanks to Jacques Caron) + +2005-02-02 + * version 2.5 + * add health checking + * add switch over + * add following to pgpool.conf + - print_time_stamp + - master_slave_mode + - connection_cache + - health_check_timeout + - health_check_period + - health_check_user + +2005-01-05 + * version 2.4 + * add reset_query_list so that SQL commands to be issued at the + end of sessions configurable + * update copyright years + +2004-12-14 + * version 2.3.3 + * make signal handling more portable + * add health check when kind does match between master and secondary + +2004-12-08 + * version 2.3.2 + * fix bug in degeneration when session is continued + +2004-11-12 + * version 2.3.1 + * fix bug after degeneration + * fix bug in child expires its life time + * fix bug when envoked with -n and sent kill signal + +2004-11-05 + * version 2.3 + * fix memory leak in handling startup packets + * implement child_life_time + * add -m option to pgpool stop mode to terminate pgpool in safe manner + +2004-10-28 + * version 2.2.1 + * restart child process if one of them detects backend errors in + single/connection pool mode. This will avoid annoying errors in + case of postmaster restarting. + * fix bug in setting select()'s timeout parameter + * fix enbug in 2.2 + * fix mishandling select()'s timeout parameters in emitting ERROR + when select() fails + * fix comments in pgpool.conf.sample + +2004-09-30 + * version 2.2 + * fix unexpected block when master or secondary receives shutdown request + * allow listen address and add new listen_address + directive. contributed by Peter Eisentraut + +2004-09-13 + * version 2.1 + * new conf param weight_master and weight_secondary + * use recent version of autoconf and automake + +2004-09-02 + * version 2.0.9 + * use non block read() to be more reliable on heavy load + * fix compilar warning on Solaris + +2004-08-18 + * version 2.0.8 + * fix segfault when connection pool timer expires (Thanks matsuu!) + +2004-08-13 + * version 2.0.7 + * fix compiler warning on PPC architecutre (thanks Peter!) + * no need flex anymore while building pgpool + (workaround is fix configure by hand. this is due to + AM_PROG_LEX macro bug). + * fix compiler warning and segfault on FreeBSD 5.2.1+AMD64 (thanks Martin!) + * fix sigint handler in child + +2004-07-22 + * version 2.0.6 + * workaorund with buggy 6.5's libpq + * fix enbug in 2.0.5(pool_read -> pool_read2) + +2004-07-19 + * version 2.0.5 + * do not check NULLMAP when no replication mode + * fix lots of compiler warnings + * change pool_read to pool_read2 + * consider the case NULLMAP is different among master and + secondary in BinaryRow + +2004-07-17 + * version 2.0.4 + * accept more connections than max_pool + * consider the case NULLMAP is different among master and secondary + +2004-07-12 + * version 2.0.3 + * fix segfault when connection is reused (enbug in 2.0.2) + * fix wording in pgpool.conf.sample + * fix flat file password authentication on V3 and relication is true + +2004-07-04 + + * version 2.0.2 + * enhance error handling when frontend or backend failed + * change "log" -> "LOG" in pool_log() + +2004-07-01 + + * version 2.0.1 + * fix bug when backend_host_name is '' + * relax message length check in SimpleForwardToFrontend so that it + allows rows order is physically different + +2004-06-22 + + * version 2.0 + * add load balancing capability + * prevent unwanted degeneration (V1.2 behavior can be possible + using replication_stop_on_mismatch directive) + +2004-05-16 + + * version 1.2.3 + * fix bug in FunctionCall in replication mode + +2004-05-11 + + * version 1.2.2 + * fix slowness when client is connected to pgpool via TCP + +2004-05-08 + + * version 1.2.1 + * fix a bug when pool_read_string() reads large string + * remove unnecessary pool_write_and_flush() from AsciiRow() and BinaryRow() + +2004-05-06 + + * version 1.2 + * fix a bug introduced by v1.1 which close listen fds accidently + * prevent buffer overflow by checking password string length + * do authentication even when connected by pooled connection + * send an end packet("X") before closing a connection to backend + +2004-04-28 + + * version 1.1 + * fix segfault when connection pool timer is expired + * support clear text password, crypt, md5 authentication method. note that in + repication mode, only clear text password authenticaton is supported. + +2004-04-23 + + * pgpool 1.0 released + + diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..3083f1a --- /dev/null +++ b/INSTALL @@ -0,0 +1 @@ +See README diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..a167cff --- /dev/null +++ b/Makefile.am @@ -0,0 +1,14 @@ +bin_PROGRAMS = pgpool + +pgpool_SOURCES = pool.h version.h pgpool.conf.sample \ + README.euc_jp \ + main.c child.c pool_auth.c pool_config.l pool_error.c \ + pool_process_query.c pool_stream.c pool_connection_pool.c pool_params.c \ + pool_signal.h pool_signal.c + +DEFS = @DEFS@ \ + -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" + +sysconf_DATA = pgpool.conf.sample + +AM_CPPFLAGS = -Wall -Wmissing-prototypes -Wmissing-declarations diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..eba5290 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,592 @@ +# Makefile.in generated by automake 1.9 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + + +SOURCES = $(pgpool_SOURCES) + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +top_builddir = . +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +INSTALL = @INSTALL@ +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +bin_PROGRAMS = pgpool$(EXEEXT) +subdir = . +DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \ + $(srcdir)/Makefile.in $(srcdir)/config.h.in \ + $(top_srcdir)/configure AUTHORS COPYING ChangeLog INSTALL NEWS \ + TODO depcomp install-sh missing mkinstalldirs pool_config.c +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.in +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ + configure.lineno configure.status.lineno +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = config.h +CONFIG_CLEAN_FILES = +am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)" +binPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(bin_PROGRAMS) +am_pgpool_OBJECTS = main.$(OBJEXT) child.$(OBJEXT) pool_auth.$(OBJEXT) \ + pool_config.$(OBJEXT) pool_error.$(OBJEXT) \ + pool_process_query.$(OBJEXT) pool_stream.$(OBJEXT) \ + pool_connection_pool.$(OBJEXT) pool_params.$(OBJEXT) \ + pool_signal.$(OBJEXT) +pgpool_OBJECTS = $(am_pgpool_OBJECTS) +pgpool_LDADD = $(LDADD) +DEFAULT_INCLUDES = -I. -I$(srcdir) -I. +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +LEXCOMPILE = $(LEX) $(LFLAGS) $(AM_LFLAGS) +SOURCES = $(pgpool_SOURCES) +DIST_SOURCES = $(pgpool_SOURCES) +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +sysconfDATA_INSTALL = $(INSTALL_DATA) +DATA = $(sysconf_DATA) +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) +am__remove_distdir = \ + { test ! -d $(distdir) \ + || { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \ + && rm -fr $(distdir); }; } +DIST_ARCHIVES = $(distdir).tar.gz +GZIP_ENV = --best +distuninstallcheck_listfiles = find . -type f -print +distcleancheck_listfiles = find . -type f -print +ACLOCAL = @ACLOCAL@ +AMDEP_FALSE = @AMDEP_FALSE@ +AMDEP_TRUE = @AMDEP_TRUE@ +AMTAR = @AMTAR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ \ + -DDEFAULT_CONFIGDIR=\"$(sysconfdir)\" + +DEPDIR = @DEPDIR@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LEX = @LEX@ +LEXLIB = @LEXLIB@ +LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LTLIBOBJS = @LTLIBOBJS@ +MAKEINFO = @MAKEINFO@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PGSQL_INCLUDE_DIR = @PGSQL_INCLUDE_DIR@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_STRIP = @ac_ct_STRIP@ +am__fastdepCC_FALSE = @am__fastdepCC_FALSE@ +am__fastdepCC_TRUE = @am__fastdepCC_TRUE@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build_alias = @build_alias@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +host_alias = @host_alias@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +pgpool_SOURCES = pool.h version.h pgpool.conf.sample \ + README.euc_jp \ + main.c child.c pool_auth.c pool_config.l pool_error.c \ + pool_process_query.c pool_stream.c pool_connection_pool.c pool_params.c \ + pool_signal.h pool_signal.c + +sysconf_DATA = pgpool.conf.sample +AM_CPPFLAGS = -Wall -Wmissing-prototypes -Wmissing-declarations +all: config.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +.SUFFIXES: .c .l .o .obj +am--refresh: + @: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \ + cd $(srcdir) && $(AUTOMAKE) --gnu \ + && exit 0; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + echo ' $(SHELL) ./config.status'; \ + $(SHELL) ./config.status;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(srcdir) && $(AUTOCONF) +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) + +config.h: stamp-h1 + @if test ! -f $@; then \ + rm -f stamp-h1; \ + $(MAKE) stamp-h1; \ + else :; fi + +stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status config.h +$(srcdir)/config.h.in: $(am__configure_deps) + cd $(top_srcdir) && $(AUTOHEADER) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f config.h stamp-h1 +install-binPROGRAMS: $(bin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)" + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-binPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(bin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \ + rm -f "$(DESTDIR)$(bindir)/$$f"; \ + done + +clean-binPROGRAMS: + -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) +pgpool$(EXEEXT): $(pgpool_OBJECTS) $(pgpool_DEPENDENCIES) + @rm -f pgpool$(EXEEXT) + $(LINK) $(pgpool_LDFLAGS) $(pgpool_OBJECTS) $(pgpool_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/child.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_auth.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_config.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_connection_pool.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_error.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_params.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_process_query.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_signal.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_stream.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \ +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.l.c: + $(LEXCOMPILE) $< + sed '/^#/ s|$(LEX_OUTPUT_ROOT)\.c|$@|' $(LEX_OUTPUT_ROOT).c >$@ + rm -f $(LEX_OUTPUT_ROOT).c +uninstall-info-am: +install-sysconfDATA: $(sysconf_DATA) + @$(NORMAL_INSTALL) + test -z "$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)" + @list='$(sysconf_DATA)'; for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + f=$(am__strip_dir) \ + echo " $(sysconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(sysconfdir)/$$f'"; \ + $(sysconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(sysconfdir)/$$f"; \ + done + +uninstall-sysconfDATA: + @$(NORMAL_UNINSTALL) + @list='$(sysconf_DATA)'; for p in $$list; do \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(sysconfdir)/$$f'"; \ + rm -f "$(DESTDIR)$(sysconfdir)/$$f"; \ + done + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(DISTFILES) + $(am__remove_distdir) + mkdir $(distdir) + @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ + list='$(DISTFILES)'; for file in $$list; do \ + case $$file in \ + $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ + $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ + esac; \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test "$$dir" != "$$file" && test "$$dir" != "."; then \ + dir="/$$dir"; \ + $(mkdir_p) "$(distdir)$$dir"; \ + else \ + dir=''; \ + fi; \ + if test -d $$d/$$file; then \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done + -find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \ + ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -400 -exec chmod a+r {} \; -o \ + ! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \ + || chmod -R a+r $(distdir) +dist-gzip: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +dist-bzip2: distdir + tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2 + $(am__remove_distdir) + +dist-tarZ: distdir + tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z + $(am__remove_distdir) + +dist-shar: distdir + shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + $(am__remove_distdir) + +dist-zip: distdir + -rm -f $(distdir).zip + zip -rq $(distdir).zip $(distdir) + $(am__remove_distdir) + +dist dist-all: distdir + tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + $(am__remove_distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + case '$(DIST_ARCHIVES)' in \ + *.tar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\ + *.tar.bz2*) \ + bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\ + *.tar.Z*) \ + uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ + *.shar.gz*) \ + GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\ + *.zip*) \ + unzip $(distdir).zip ;;\ + esac + chmod -R a-w $(distdir); chmod a+w $(distdir) + mkdir $(distdir)/_build + mkdir $(distdir)/_inst + chmod a-w $(distdir) + dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \ + && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \ + && cd $(distdir)/_build \ + && ../configure --srcdir=.. --prefix="$$dc_install_base" \ + $(DISTCHECK_CONFIGURE_FLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \ + distuninstallcheck \ + && chmod -R a-w "$$dc_install_base" \ + && ({ \ + (cd ../.. && umask 077 && mkdir "$$dc_destdir") \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \ + && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \ + distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \ + } || { rm -rf "$$dc_destdir"; exit 1; }) \ + && rm -rf "$$dc_destdir" \ + && $(MAKE) $(AM_MAKEFLAGS) dist \ + && rm -rf $(DIST_ARCHIVES) \ + && $(MAKE) $(AM_MAKEFLAGS) distcleancheck + $(am__remove_distdir) + @(echo "$(distdir) archives ready for distribution: "; \ + list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \ + sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}' +distuninstallcheck: + @cd $(distuninstallcheck_dir) \ + && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \ + || { echo "ERROR: files left after uninstall:" ; \ + if test -n "$(DESTDIR)"; then \ + echo " (check DESTDIR support)"; \ + fi ; \ + $(distuninstallcheck_listfiles) ; \ + exit 1; } >&2 +distcleancheck: distclean + @if test '$(srcdir)' = . ; then \ + echo "ERROR: distcleancheck can only run from a VPATH build" ; \ + exit 1 ; \ + fi + @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \ + || { echo "ERROR: files left in build directory after distclean:" ; \ + $(distcleancheck_listfiles) ; \ + exit 1; } >&2 +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) $(DATA) config.h +installdirs: + for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sysconfdir)"; do \ + test -z "$$dir" || $(mkdir_p) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." + -rm -f pool_config.c +clean: clean-am + +clean-am: clean-binPROGRAMS clean-generic mostlyclean-am + +distclean: distclean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-exec-am: install-binPROGRAMS install-sysconfDATA + +install-info: install-info-am + +install-man: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f $(am__CONFIG_DISTCLEAN_FILES) + -rm -rf $(top_srcdir)/autom4te.cache + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-binPROGRAMS uninstall-info-am \ + uninstall-sysconfDATA + +.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \ + clean-binPROGRAMS clean-generic ctags dist dist-all dist-bzip2 \ + dist-gzip dist-shar dist-tarZ dist-zip distcheck distclean \ + distclean-compile distclean-generic distclean-hdr \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-binPROGRAMS install-data install-data-am install-exec \ + install-exec-am install-info install-info-am install-man \ + install-strip install-sysconfDATA installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ + ps ps-am tags uninstall uninstall-am uninstall-binPROGRAMS \ + uninstall-info-am uninstall-sysconfDATA + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..f84d2f7 --- /dev/null +++ b/NEWS @@ -0,0 +1,390 @@ +2.5.1(kaku) 2005/2/14(Mon) + + o 2.5¤ÇÄɲ䵤줿health checkµ¡Ç½¤Î¥Ð¥°½¤Àµ + + - ¼¡¤Îhealth check¤òÂԤĴ֤Ëchild_life_time¤¬expire¤·¤ÆSIGCHLD¤Ê + ¤É¤¬¾å¤¬¤ë¤Èhealth check¤Î´Ö³Ö¤¬Àµ¤·¤¯¤Ê¤¯¤Ê¤ëÌäÂê¤ò½¤Àµ + + - health check¤ÎÃæ¤ÇconnectÂÔ¤Á¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È¤­¤Ë¤¿¤Þ¤¿¤Þ + child_life_time¤¬exire¤·¤ÆSIGCHLD¤¬¾å¤¬¤ë¤È¥¨¥é¡¼¤Èǧ¼±¤µ¤ì + ¤Æ¤·¤Þ¤¦failover¤·¤Æ¤·¤Þ¤¦ÌäÂê¤ò½¤Àµ + + o smart shutdownÃæ¤Ëfast/immediate shutdown request¤¬¤¢¤Ã¤¿¤é¤½¤ì¤ò¼õ¤± + ÉÕ¤±¤ë¤è¤¦¤Ë¤·¤¿(°ÊÁ°¤Ï¥Ö¥í¥Ã¥¯¤·¤Æ¤¤¤¿) + + o °Û¤Ê¤ë¥×¥í¥»¥¹¤Î¥í¥°½ÐÎϤ¬º®¤¸¤Ã¤Æ¤·¤Þ¤¦¤Î¤òasprintf¤ò»È¤Ã¤Æ²ó + Èò¤¹¤ë¤è¤¦¤Ë¤·¤¿(Thanks to Jacques Caron) + +2.5(kaku) 2005/2/2(Tue) + + °Ê²¼¤Îµ¡Ç½¤òÄɲᥠ+ - ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð(pgpool switch¥ª¥×¥·¥ç¥ó) + - health check + - pgpool.conf¤Ë°Ê²¼¤òÄɲà + - print_time_stamp(¥í¥°¤Ø¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×°õ»úµ¡Ç½) + - master_slave_mode(¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ê¤·¡¤¥»¥«¥ó¥À¥ê¤Ë¤ÏÈó¥È¥é + ¥ó¥¶¥¯¥·¥ç¥ó¤ÎSELECT¤Î¤ßȯ¹Ô) + - connection_cache(¥³¥Í¥¯¥·¥ç¥ó¥­¥ã¥Ã¥·¥å¤Îon/off) + - health_check_timeout(¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤Î¥¿¥¤¥à¥¢¥¦¥ÈÃÍ) + - health_check_period(¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤Î´Ö³Ö) + - health_check_user(¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤Î¥æ¡¼¥¶Ì¾) + + ¥Ð¥°½¤Àµ + - child_life_time¤Î¥¢¥ë¥´¥ê¥º¥à¤Î¸«Ä¾¤·¡¥Éé²Ù¤Î¹â¤¤¤È¤­¤ËÀµ³Î¤Ë + child_life_time¤ò·×»»¤Ç¤­¤Ê¤¤ÌäÂ꤬¤¢¤ê¡¤¤Þ¤¿select(2)¤Î¸Æ¤Ó½Ð + ¤·¤¬ÉÑÈˤ¹¤®¤ëÌäÂê¤ò½¤Àµ + +2.4(kahala) 2005/1/5(Thu) + + ¥»¥Ã¥·¥ç¥ó¤Î½ªÎ»»þ¤Ëȯ¹Ô¤¹¤ëSQL¥³¥Þ¥ó¥É¤òpgpool.conf¤ÇÀßÄê²Äǽ¤Ë + ¤·¤¿(reset_query_list¤ÎÄɲÃ)¡¥ + + Copyright¤ò2005ǯÂбþ¤Ë¡¥ + +2.3.3(iheihe) 2004/12/14(Tue) + + ½ÌÂà½èÍý¤Ë´Ø¤·¤Æsignal handler¤òÂç²þ½¤¤·¤Æ¤è¤ê¥Ý¡¼¥¿¥Ö¥ë¤Ê¥³¡¼¥Ç¥£ + ¥ó¥°¤Ë¤·¤¿¡¥¤³¤ì¤Ë¤è¤êSolaris¤Ç¤â°ÂÄꤷ¤Æ½ÌÂà½èÍý¤¬Æ°¤¯¤è¤¦¤Ë¤Ê¤Ã + ¤¿(¾ÜºÙ¤Ï¡Ö[pgsql-jp: 34346] pgpool 2.3.1 ¤Ç½ÌÂ౿ž¤Ë¼ºÇÔ¤·¤Þ¤¹¡× + ¤Î¥¹¥ì¥Ã¥É¤ò»²¾È) + + ¥Ñ¥±¥Ã¥È¤Î¼ïÎà¤ÎÉÔÀ°¹ç¤¬µ¯¤­¤¿¤È¤­¤Ë¡¤¼ÂºÝ¤ËPostgreSQL¤¬¥À¥¦¥ó¤· + ¤Æ¤¤¤ë¤«¤É¤¦¤«¥Á¥§¥Ã¥¯¤¹¤ëhealth check¤òÄɲä·¤¿¡¥¤³¤ì¤Ë¤è¤ê¡¤³Î + ¼Â¤Ë¥µ¡¼¥Ð¥À¥¦¥ó¤ò¸¡ÃΤǤ­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤È¶¦¤Ë¡¤¥¢¥×¥ê¥±¡¼¥·¥ç¥ó + ¤«¤é¤Î̵Â̤Êretry¤òºÇ¾®¸Â¤Ë¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥ + +2.3.2(iheihe) 2004/12/8(Wed) + + »Ò¥×¥í¥»¥¹¤¬¥»¥Ã¥·¥ç¥ó¤ò½ªÎ»¤»¤º¤Ë½ÌÂह¤ë¤È¡¤»Ò¥×¥í¥»¥¹¤¬½ªÎ»¤·¤Ê + ¤¤¥Ð¥°¤ò½¤Àµ¡¥2.3¤Ç¡¤»Ò¥×¥í¥»¥¹¤ËSIGTERM¤¬Á÷¤é¤ì¤¿¤È¤­¤Ë¥»¥Ã¥·¥ç + ¥ó¤¬½ªÎ»¤¹¤ë¤Þ¤ÇÂԤĤ褦¤Ë¤·¤¿¤³¤È¤¬¸¶°ø¡¥SIGQUIT¤òÁ÷¤ë¤è¤¦¤Ë¤· + ¤ÆÂн补 + +2.3.1(iheihe) 2004/11/12(Fri) + + ¥Þ¥¹¥¿¤¬¤³¤±¤Æ½ÌÂ౿ž¤¹¤ë¤È¤­¤Ë¡¤°ìö¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤¹¤ë¤³¤È¤Ê¤· + ¤Ëľ¤Á¤Ë¥»¥«¥ó¥À¥ê¤Ë½ÌÂà¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¥ + + master¤Èsecondary¤Î¶èÊ̤òSIGUSR1¤ÈSIGUSR2¤Ç¹Ô¤¤¡¤½ÌÂà¸å¤¿¤Þ¤ËÀÜ + ³¤ò¼õ¤±ÉÕ¤±¤Ê¤¯¤Ê¤ë¥Ð¥°¤ò½¤Àµ + + child_life_time¤òexpire¤·¤¿¤È¤­¤Ë¥»¥«¥ó¥À¥ê¤Ë½ªÎ»¥Ñ¥±¥Ã¥È¤¬Á÷¤é + ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¥Ð¥°¤ò½¤Àµ + + »Ò¥×¥í¥»¥¹¤Î½ªÎ»¥¹¥Æ¡¼¥¿¥¹¤¬0°Ê³°¤Î»þ¤Î¤ß»Ò¥×¥í¥»¥¹¤òºÆµ¯Æ°¤¹¤ë + ¤è¤¦¤Ë¤·¤¿¡¥¤³¤ì¤Ë¤è¤Ã¤Ætty¤òdetach¤»¤º¤Ë±¿ÍѤ·¤Æ¤¤¤ÆÃ¼Ëö¤«¤é + kill¤òÁ÷¤Ã¤¿¤È¤­¤Ëwait()¥ë¡¼¥×¤Ç¿Æ¥×¥í¥»¥¹¤¬ÂÔ¤Á³¤±¤ë¥Ð¥°¤ò²óÈò + ¤·¤¿¡¥ + +2.3(iheihe) 2004/11/05(Fri) + + startup packet¤Î¥á¥â¥ê¡¼¥ê¡¼¥¯¤ò½¤Àµ + + child_life_time¤ò¼ÂÁõ + + pgpool {[-m {s[mart]|f[ast]|i[mmediate]}] stop]¤ò¼ÂÁõ¡¥¥Õ¥í¥ó¥È + ¥¨¥ó¥É¤ÎÀܳ½ªÎ»¤òÂԤäưÂÁ´¤ËÄä»ß¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¥ + +2.2.1(hilu) 2004/10/28(Thu) + + ¥Ð¥Ã¥¯¥¨¥ó¥É1Âæ¤Î¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¥â¡¼¥É¤Ë¤ª¤¤¤Æ¡¤¥Ð¥Ã¥¯¥¨¥ó¥É + ¤¬ºÆµ¯Æ°¤·¤¿¤È¤­¤Ëpgpool¤¬¤½¤Î¤³¤È¤ò¸¡½Ð¤Ç¤­¤º¡¤¸Ä¡¹¤Î¥³¥Í¥¯¥·¥ç + ¥ó¤Ë¤ª¤±¤ëºÇ½é¤ÎÌ䤤¹ç¤ï¤»¤Ç¥¨¥é¡¼¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦ÌäÂê¤ò²óÈò¤¹¤ë¤¿ + ¤á¤Ë¡¤¤¢¤ë¥³¥Í¥¯¥·¥ç¥ó¤Ç¥¨¥é¡¼¤ò¸¡½Ð¤·¤¿¤é¡¤pgpool¤Î»Ò¥×¥í¥»¥¹¤ò + ºÆµ¯Æ°¤¹¤ë¤è¤¦¤Ë¤·¤¿¡¥ + + [pgsql-jp: 34117]¤Ç¤Î¥Ð¥°»ØÅ¦Âбþ¡¥select()¤ËÅϤ¹¥¿¥¤¥à¥¢¥¦¥È¥Ñ + ¥é¥á¡¼¥¿¤ÎÀßÄê¥ß¥¹¡¥ + + [pgsql-jp: 34157]¤Ç¤Î¥Ð¥°»ØÅ¦Âбþ¡¥¸¶°ø¤Ï2.2¤Ç¤Î<[pgsql-jp: + 34005]¤Ç¤Î¥Ð¥°»ØÅ¦Âбþ>¤Ë¤è¤ë¥¨¥ó¥Ð¥°¡¥MASTER¤ÈSECONDARY¤ÎƱ´ü¤ò + ¼è¤ë¤¿¤á¤Ë̵¾ò·ï¤ËSECONDARY¤«¤é¤Î¥Ç¡¼¥¿¤ÎÅþÃå¤òselect()¤ÇÂÔ¤Ã¤Æ + ¤¤¤ë¤Î¤Ï´Ö°ã¤¤¡¥read¥Ð¥Ã¥Õ¥¡¤Ë¥Ç¡¼¥¿¤¬»Ä¤Ã¤Æ¤¤¤ë¤«¤É¤¦¤«Àè¤Ë¥Á¥§¥Ã + ¥¯¤¹¤Ù¤­¤À¤Ã¤¿¡¥2.1°ÊÁ°¤Ï̵¾ò·ï¤Ëpool_read()¤·¤Æ¤¤¤¿¤Î¤ÇOK¤À¤Ã¤¿¡¥ + + [pgsql-jp: 34161]¥Ð¥°»ØÅ¦Âбþ¡¥select()¤ËÅϤ¹¥¿¥¤¥à¥¢¥¦¥È¥Ñ + ¥é¥á¡¼¥¿¤Ïselect()¤«¤éreturn¸å¡¤¥¯¥ê¥¢¤µ¤ì¤ë¤Î¤ò˺¤ì¤Æ¤¤¤¿¡¥ + + pgpool.conf.sample¤ÎÃæ¤Î¥³¥á¥ó¥È¤Î´Ö°ã¤¤¤ò½¤Àµ + +2.2(hilu) 2004/09/30(Thu) + + [pgsql-jp: 34005]¤Ç¤Î¥Ð¥°»ØÅ¦Âбþ¡¥ + ¥Þ¥¹¥¿¡¦¥»¥«¥ó¥À¥ê¤¬¥·¥ã¥Ã¥È¥À¥¦¥ó»þ¤Ëpgpool¤Ënotice message¤òÅꤲ¤ë + pgpool¤Ï¤½¤ì¤ò¼õ¤±¤È¤Ã¤¿¤Î¤Ç¡¤¥»¥«¥ó¥À¥ê¤«¤é¤ânotice message¤¬Íè¤ë + ¤â¤Î¤È»×¤Ã¤ÆÂÔ¤Á³¤±¤ë + + TCP/IP¤Î¼õ¤±ÉÕ¤±¥¢¥É¥ì¥¹¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿(listen_address¤Î + ÄɲÃ)¡¥(Peter Eisentraut»á¤«¤é¤Î¹×¸¥) + +2.1(hebe) 2004/09/13(Mon) + + ¥í¡¼¥É¥Ð¥é¥ó¥¹»þ¤Ë¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Ë½Å¤ß¤òÉÕ¤±¤ë¤¿¤á¤Î¥Ñ¥é¥á¡¼ + ¥¿weight_master¤Èweight_secondary¤òÄɲà + + autoconf 2.59¡¤automake 1.9¤ò»ÈÍѤ¹¤ë¤è¤¦¤Ë¤·¤¿ + +2.0.9(heemauli) 2004/09/02(Thu) + + ¹âÉé²Ù»þ¤ËÂбþ¤¹¤ë¤¿¤á¤Ë¡¤read()¤ònon block¥â¡¼¥É¤Ç²ÔƯ¤µ¤»¤ë¤è + ¤¦¤Ë¤·¤¿ + + Solaris¤Ç¤Î¥³¥ó¥Ñ¥¤¥é¥ï¡¼¥Ë¥ó¥°(getpid()¤¬int¤Ç¤Ê¤¤¤Èprintf()¥Õ¥¡ + ¥ß¥ê¡¼¤¬Ê¸¶ç¤ò¸À¤¦)¤ËÂбþ + +2.0.8(heemauli) 2004/08/18(Wed) + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Ç²ÔÆ¯Ãæ¤Ë¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¤Î¥¿¥¤¥Þ¡¼¤¬Æ¯ + ¤¯¤ÈÍî¤Á¤ë¥Ð¥°¤ò½¤Àµ + +2.0.7(heemauli) 2004/08/13(Fri) + + PowerPc¥¢¡¼¥­¥Æ¥¯¥Á¥ã¾å¤Ç¤Î¥³¥ó¥Ñ¥¤¥é¥ï¡¼¥Ë¥ó¥°¤ò½¤Àµ + + ¥³¥ó¥Ñ¥¤¥ë»þ¤Ëlex/flex¤¬ÉÔÍפˤ·¤¿¡¥¤â¤È¤â¤Èflex¤¬À¸À®¤·¤¿.c¤òƱ + º­¤·¤Æ¤¤¤ë¤Î¤Çflex¤ÏÉÔÍפʤϤº¤À¤¬¡¤automake¤Î¥Þ¥¯¥í + (AM_PROG_LEX)¤¬¥Ð¥°¤Ã¤Æ¤¤¤ë¤Î¤Ç½¾Íè¤Î¥Ð¡¼¥¸¥ç¥ó¤Ç¤Ï¤³¤¦¤Ê¤Ã¤Æ¤· + ¤Þ¤Ã¤Æ¤¤¤¿¡¥¤È¤ê¤¢¤¨¤ºconfigure¤ò¼ê¤Ç½¤Àµ¤·¤ÆÂн补 + + -nÉդǵ¯Æ°¤·¤¿ºÝ¤Ë¡¤SIGINT¤ò¼õ¿®¤·¤Æ¤â½ªÎ»¤·¤Ê¤¤¤³¤È¤¬¤¢¤ë¥Ð¥°¤ò + ½¤Àµ¡¥ + + FreeBSD 5.2.1+AMD64¤Ç¤Î¥³¥ó¥Ñ¥¤¥é¥ï¡¼¥Ë¥ó¥°¤ª¤è¤Óseg fault¤ò½¤Àµ¡¥ + main.c¤Çstring.h¤òinclude¤·¤Æ¤¤¤Ê¤¤¤Ð¤«¤ê¤Ëstrerror()¤¬ÉÔÀµ¤Ê¥¢ + ¥É¥ì¥¹¤òÊÖ¤·¤Æ¤¤¤¿ÌÏÍÍ¡¥ + +2.0.6(heemauli) 2004/07/22(Thu) + + (¥Ð¥°¤Î¤¢¤ë)6.5¤Îlibpq¤ò»È¤Ã¤ÆÀܳ¤·¤¿¤È¤­¤Ë̵¸Â¥ë¡¼¥×¤¹¤ëÌäÂê¤ò + ½¤Àµ + + pool_read2¤ËÊѹ¹¤·¤¿¤È¤³¤í¤Ë¥Ð¥°¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ(enbug) + +2.0.5(heemauli) 2004/07/19(Mon) + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Ç¤Ê¤¤¤È¤­¤Ë¤âNULLMAP¤Î¥Á¥§¥Ã¥¯¤ò¤·¤Æ¤¤¤¿ + ¥Ð¥°¤ò½¤Àµ + + ¥³¥ó¥Ñ¥¤¥ë»þ¤Î¥¨¥é¡¼¥Á¥§¥Ã¥¯¤ò¸·¤·¤¯¤·¡¤¥ï¡¼¥Ë¥ó¥°¤ò¼è¤Ã¤¿ + + ̵Â̤Ëpool_read¤ò»È¤Ã¤Æ¤¤¤ë¤È¤³¤í¤òpool_read2¤ËÊѹ¹ + + BinaryRow¤Ç¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ÇNULLMAP¤¬°ã¤Ã¤Æ¤¤¤Æ¤âÂç¾æÉפʤ褦¤Ë¤·¤¿ + +2.0.4(heemauli) 2004/07/17(Sat) + + ¥³¥Í¥¯¥·¥ç¥ó¥¹¥í¥Ã¥È¤¬°ìÇդˤʤ俤Ȥ­(max_pool¤ËÅþ㤷¤¿¤È¤­)¡¤ + °ìÈָŤ¤¥³¥Í¥¯¥·¥ç¥ó¤ò¼Î¤Æ¤Æ¡¤¿·¤·¤¤¥³¥Í¥¯¥·¥ç¥ó¤òºî¤ì¤ë¤è¤¦¤Ë¤· + ¤¿¡¥ + + ¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ÇNULLMAP¤¬°ã¤Ã¤Æ¤¤¤Æ¤âÂç¾æÉפʤ褦¤Ë¤·¤¿¡¥ + +2.0.3(heemauli) 2004/07/12(Mon) + + ¥³¥Í¥¯¥·¥ç¥ó¤òºÆÍøÍѤ·¤è¤¦¤È¤·¤¿¤È¤­¤Ë¡¤¥×¥í¥»¥¹¤¬Íî¤Á¤ëÌäÂê¤ò½¤ + Àµ(2.0.2¤Ç¤Îenbug¤Î½¤Àµ) + + pgpool.conf.sample¤Îreplication_stop_on_mismatch¤Î¥¹¥Ú¥ë¥ß¥¹¤ò½¤ + Àµ + + V3¥×¥í¥È¥³¥ë¤«¤Äreplication¤¬Í­¸ú¤Î»þ¤Ëflat file password + authentication¤¬Æ°ºî¤·¤Ê¤¤ÌäÂê¤ò½¤Àµ + +2.0.2(heemauli) 2004/07/04(Sun) + + ¥Õ¥í¥ó¥È¥¨¥ó¥É¤ä¥Ð¥Ã¥¯¥¨¥ó¥É¤¬°Û¾ï½ªÎ»¤·¤¿¤È¤­¤Î¥¨¥é¡¼½èÍý¤ò¶¯²½ + + ¥í¥°¥á¥Ã¥»¡¼¥¸¤ÎID¤ò"log"¤«¤é"LOG"¤ËÊѹ¹¤·¤¿ + +2.0.1(heemauli) 2004/07/01(Thu) + + backend_host_name¤¬''¤Î¤È¤­¤Ësecondary_host_name¤Þ¤Ç''¤È¸«¤Ê¤µ¤ì + ¤Æ¤·¤Þ¤¦¥Ð¥°¤ò½¤Àµ + + ¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ÇƱ¤¸¥Æ¡¼¥Ö¥ë¤Î¹Ô¤ÎʤӤ¬ÊªÍýŪ¤Ë°Û¤Ê¤Ã¤Æ¤â¥¨ + ¥é¡¼¤Ë¤Ê¤é¤Ê¤¤¤è¤¦¤Ë¤·¤¿¡Ê¤½¤Îʬ¥Á¥§¥Ã¥¯¤¬´Å¤¯¤Ê¤Ã¤Æ¤¤¤ë¤¬¤ä¤à¤ò + ÆÀ¤Ê¤¤¡Ë + +2.0(heemauli) 2004/06/22(Tue) + + V3¥×¥í¥È¥³¥ë¤ËnativeÂбþ¤·¤¿¡¥ + Éé²Ùʬ»¶¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿ + ¥Ç¡¼¥¿¤ÎÉÔ°ìÃ×»þ¤Ë¶¯À©½ÌÂ౿ž¤¹¤ë¤«¤É¤¦¤«ÁªÂò¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿ + +1.2.3((hapuupuu) 2004/05/16(Sun) + + ¥é¡¼¥¸¥ª¥Ö¥¸¥§¥¯¥È¡ÊÀµ³Î¤Ë¤ÏFunctionCall¡Ë¤Î¥ì¥×¥ê¥±¡¼¥·¥ç¥óưºî + ¤Ë¥Ð¥°¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ¡¥ + +1.2.2(hapuupuu) 2004/05/12(Wed) + + ¥¯¥é¥¤¥¢¥ó¥È¤ÈTCP¤ÇÀܳ¤·¤¿¤È¤­¤Ë¡¤pgbench -C¤¬Èó¾ï¤ËÃÙ¤¤ÌäÂê¤Ë + Âн补 + + - pool_read()¤Ç¡¤É¬¤ºREADBUSZ¥Ð¥¤¥ÈÆÉ¤ß¹þ¤à¡¥Í¾¤Ã¤¿¥Ú¥ó¥Ç¥£¥ó + ¥°¥Ç¡¼¥¿¤Ë¤¹¤ë + + - CursorResponse, RowDescription, AsciiRow, BinaryRow, + CompleteCommandResponse¤Çflush()¤ò»ß¤á¤ë¡¥¤³¤ì¤é¤Ï + ReadyForQuery¤Þ¤Ç°ìÏ¢¤Î¥á¥Ã¥»¡¼¥¸¤È¤·¤Æ¥Ð¥Ã¥¯¥¨¥ó¥É¤«¤éή¤ì + ¤Æ¤¯¤ë¤Î¤Ç¡¤ÅÓÃæ¤Îflush()¤ÏɬÍפʤ¤¡¥ + + POOL_CONNECTION¹½Â¤ÂΤ«¤éÉÔɬÍפʥá¥ó¥Ð¤òºï½ü + + pool_close()¤Ç2½Åclose¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ + +1.2.1(hapuupuu) 2004/05/08(Sat) + + pool_read_string()¤¬Â礭¤Êʸ»úÎó¤òÆÉ¤à¤È¤­¤Î¥Ð¥°¤ò½¤Àµ¡¥ + + AsciiRow()¤ÈBinaryRow()¤«¤éÉÔɬÍפÊpool_write_and_flush()¤òºï½ü¡¤ + pool_write()¤ËÃÖ¤­´¹¤¨¤¿¡¥ + +1.2(hapuupuu) 2004/05/06(Thu) + + 1.1¤Î»þ¤Ë¡¤¿Æ¥×¥í¥»¥¹¤ÎÃæ¤Çlisten fd¤ò´Ö°ã¤Ã¤Æclose¤·¤Æ¤¤¤¿¤Î¤ò + ¸µ¤ËÌᤷ¤¿¡¥ + + ¥Ñ¥¹¥ï¡¼¥É¥Ñ¥±¥Ã¥È¤ò¼õ¿®¤¹¤ë¤È¤­¤Ë¡¤¥Ñ¥¹¥ï¡¼¥É¤ÎŤµ¤¬¥Á¥§¥Ã¥¯¤µ + ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¤Î¤ò½¤Àµ¡¥ + + ¥³¥Í¥¯¥·¥ç¥ó¤òºÆÍøÍѤ¹¤ëºÝ¤Ë¡¤²þ¤á¤ÆÇ§¾Ú¤ò¹Ô¤¦¤è¤¦¤Ë¤·¤¿¡¥¤³¤¦¤· + ¤Ê¤¤¤Èǧ¾Ú¤Ê¤·¤Ç¥³¥Í¥¯¥·¥ç¥ó¤òÍøÍѤǤ­¤Æ¤·¤Þ¤¦¡¥ + + ¥Ð¥Ã¥¯¥¨¥ó¥É¤È¤ÎÀܳ¤òÀÚ¤ë¤È¤­¤Ë¡¤¤¤¤­¤Ê¤êclose¤¹¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¤ + ½ªÎ»¥Ñ¥±¥Ã¥È("X")¤òÁ÷¤ë¤è¤¦¤Ë¤·¤¿¡¥ + +1.1(hahalalu) 2004/04/29(Thu) + + connection_life_time¤¬0°Ê³°¤Î¤È¤­¡¤¤Ë¥¿¥¤¥Þ¡¼´Æ»ë¥ë¡¼¥Á¥ó¤ÎÃæ¤Ç + segfault¤¹¤ë¥Ð¥°¤ò½¤Àµ¡¥ + + clear text password/crypt/md5ǧ¾Ú¤ò¼ÂÁõ¡¥¤¿¤À¤·¡¤clear text + passwordǧ¾Ú°Ê³°¤Ï¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Ç¤Ïư¤­¤Þ¤»¤ó¡¥¤³¤ì¤Ï + salt¤ò»öÁ°¤Ë¥Ð¥Ã¥¯¥¨¥ó¥É¤«¤é¥Õ¥í¥ó¥È¥¨¥ó¥É¤ËÁ÷¿®¤·¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê + ¤¤¥×¥í¥È¥³¥ë¤ÎÀ­¼Á¼«ÂΤ˵¯°ø¤¹¤ë¤â¤Î¤Ç¤¹¡¥ + +1.0(ehu) official release 2004/4/23(Fri) + + ¥É¥­¥å¥á¥ó¥ÈÎà¤Î¤ß¤Î½¤Àµ¡¥ + +1.0(ehu) beta4 2004/4/21(Wed) + + pid¥Õ¥¡¥¤¥ë¤Î»Ä³¼¤¬»Ä¤Ã¤Æ¤¤¤Æ¤âµ¯Æ°¤Ç¤­¤ë¤è¤¦¤Ë½¤Àµ¤·¤¿¡¥ + +1.0(ehu) beta3 2004/4/18(Sun) + + strict¥â¡¼¥É»þ¤Ë¤â´Ø¤ï¤é¤º¥¿¥¤¥à¥¢¥¦¥È¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¥Ð¥°¤ò + ½¤Àµ¡¥¤Þ¤¿¡¤¹¹¿··Ï¤Ë¤Ä¤¤¤Æ¤Ïstrict¥â¡¼¥É¤Ç¤â¤½¤¦¤Ç¤Ê¤¯¤Æ¤â¤µ¤Û¤É + À­Ç½¤¬ÊѤï¤é¤Ê¤¤¤³¤È¤¬¤ï¤«¤Ã¤¿¤Î¤Ç¡¤strict¥â¡¼¥É¤ò¥Ç¥Õ¥©¥ë¥È¤Ë¤· + ¤¿¡¥ + +1.0(ehu) beta2 2004/4/17(Sat) + + AsciiRow()´Ø¿ô¤Ç¡¤¥»¥«¥ó¥À¥ê¤«¤é¤ÎÆÉ¤ß¥Ð¥¤¥È¿ô¤Ëntoh¤ò¤«¤Þ¤¹¤Î¤ò + ˺¤ì¤Æ¤¤¤¿¤¿¤á¤Ë¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Î½èÍý¤ÎƱ´ü¤¬¤º¤ì¡¤¥¨¥é¡¼¤Ë¤Ê¤Ã + ¤Æ¾¡¼ê¤Ë¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤·¤Æ¤·¤Þ¤¦¥Ð¥°¤ò½¤Àµ¡¥ + +1.0(ehu) beta1 2004/4/13(Tue) + + show pool_status¤Ë¤è¤ëÆâÉô¾õÂÖɽ¼¨µ¡Ç½¤òÄɲᥠ+ htnos/htnol¤Î»È¤¤Êý¤¬´Ö°ã¤Ã¤Æ¤¤¤ë¤È¤³¤í¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ¡ÊSolaris + ¤Ç¤¦¤Þ¤¯Æ°ºî¤·¤Ê¤¤¡¤¤È¤¤¤¦Êó¹ð¤È´Ø·¸¤¬¤¢¤ë¤«¤âÃΤì¤Ê¤¤¡Ë + +1.0(ehu) alpha 1 2004/3/29(Mon) + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¼ÂÁõ¤·¤¿¥¢¥ë¥Õ¥¡¥Ð¡¼¥¸¥ç¥ó¥ê¥ê¡¼¥¹¡¥°Ê¸å0.2·Ï + Îó¤Ï¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¥ê¥ê¡¼¥¹¤Î¤ß¤È¤¹¤ë¡¥ + +0.2.2(auku) 2004/3/25(Thu) + + 0.2.1¤Î»þ¤Ëenbug¤·¤ÆV3¥×¥í¥È¥³¥ë¤Ø¤ÎÂбþ¤¬¤Ç¤­¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿¤Î¤ò + ½¤Àµ¡¥ + +0.2.1(aulepe) 2004/3/24(Wed) + + copyright notice¤ò¹¹¿· + cancel request¤ò¼ÂÁõ + +0.2.0(au) 2004/2/28(Sat) + + ÀßÄê¹àÌܤËbackendÍѤÎUnix domain socket¤Î¥Ç¥£¥ì¥¯¥È¥ê¥Ñ¥¹¤È + "backend_socket_dir"¤òÄɲᥥǥե©¥ë¥È¤Ï/tmp¡¥Debin¤Ç + ¤Ï/var/run/postgresql¤Ç¤¢¤ë¤³¤È¤Ø¤ÎÂкö¤¬¼çÌÜŪ¡¥ + + Ê»¤»¤Æ¡¤"socket_dir"¤ÎÀßÄ꤬¤¦¤Þ¤¯¤¤¤Ã¤Æ¤¤¤Ê¤¤¥Ð¥°¤ò½¤Àµ¡¥ + +0.1.9 (aawa) 2004/2/27(Fri) + + V3¥×¥í¥È¥³¥ë¤Ç¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬ÀܳÍ×µá¤ò¤·¤Æ¤­¤¿¤é¡¤V2¤Ëfallback + ¥ê¥¯¥¨¥¹¥È¤¹¤ë¤è¤¦¤Ë¤·¤¿¡¥¤³¤ì¤Ç°ì±þ7.4°Ê¹ß¤Î¥Õ¥í¥ó¥È¥¨¥ó¥É¤Ç¤â + Àܳ¤Ç¤­¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¤Ï¤º¡¥ + + ÀßÄê¹àÌܤËUnix domain socket¤Î¥Ç¥£¥ì¥¯¥È¥ê¥Ñ¥¹¤Ç¤¢¤ë"socket_dir" + ¤òÄɲᥥǥե©¥ë¥È¤Ï/tmp¡¥Debin¤Ç¤Ï/var/run/postgresql¤Ç¤¢¤ë¤³¤È + ¤Ø¤ÎÂкö¤¬¼çÌÜŪ¡¥ + +0.1.8 (palia) 2004/2/5(Wed) + + AsciiRow¥×¥í¥È¥³¥ë¤Ç¡¤¥Ç¡¼¥¿¥µ¥¤¥º¤¬0¤Î¤È¤­¤Î½èÍý¤¬È´¤±¤Æ¤¤¤¿¤Î + ¤ò½¤Àµ¡¥¾ÜºÙ¤Ï[pgcluster: 78]¤ò»²¾È¡¥ + +0.1.7 (omao) 2004/1/21(Wed) + ¶õ¤ÎÌ䤤¹ç¤ï¤»¤¬ÆþÎϤµ¤ì¤¿¤È¤­¤Ë¥¨¥é¡¼½ªÎ»¤¹¤ë¥Ð¥°¤ò½¤Àµ(thanks + to tanida@sra.co.jp) + README(±Ñ¸ì)¡¤README.euc_jp(ÆüËܸì)ºîÀ®¡¥ + +0.1.6 (nene) 2003/11/28(Fri) + + Â礭¤Ê¥µ¥¤¥º¤ÎÌ䤤¹ç¤ï¤»¤¬ÆþÎϤµ¤ì¤¿¤È¤­¤Ë¡¤Ê¸»úÆþÎÏ¥¹¥È¥ê¡¼¥à¥â + ¥¸¥å¡¼¥ë¤Çsegmentation fault¤òµ¯¤³¤¹¥Ð¥°¤ò½¤Àµ¤·¤Þ¤·¤¿¡¥ + +0.1.5 (io) 2003/8/28(Thu) + + SSLÂбþ¤Î¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬¤Ä¤Ê¤¬¤é¤Ê¤¤ÌäÂê¤ËÂбþ¡¥ + tietew@tietew.net¤µ¤ó¡¤¥Ñ¥Ã¥Á¤ò¤¢¤ê¤¬¤È¤¦¤´¤¶¤¤¤Þ¤·¤¿¡¥ + +0.1.4 (iiwi) 2003/8/9(Sat) + + ʸ»úÆþÎÏ¥¹¥È¥ê¡¼¥à¥â¥¸¥å¡¼¥ë¤Î¥Ð¥°¤ò½¤Àµ¡¥mitani@sraw.co.jp¤µ¤ó + ¤¢¤ê¤¬¤È¤¦¤´¤¶¤¤¤Þ¤·¤¿¡¥ + +0.1.3 (elepaio) 2003/7/20(Sun) + + postgres¤Î¥Ø¥Ã¥À¡¼¥Õ¥¡¥¤¥ë¤¬¤Ê¤¯¤Æ¤â¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿¡¥ + + Solaris¤Ç libsocket, libnsl¤ò¥ê¥ó¥¯¤·¤Æ¤¤¤Ê¤¤¤Î¤Ç¥¨¥é¡¼¤Ë¤Ê¤ë·ï + ¤ò½¤Àµ(configure.in¤ËAC_CHECK_LIB¤òÄɲÃ)¡¥ + + FreeBSD, Solaris¤Ç¤Ï¡¤Linux¤È°ã¤Ã¤Æaccept()¤Îfd¤¬non block¤Ë¤Ê¤Ã + ¤Æ¤¤¤ë¾ì¹ç¡¤accept()¤¬ÊÖ¤¹fd¤ânon block¤Ë¤Ê¤Ã¤Æ¤·¤Þ¤¦¡¥accept() + ¤¬ÊÖ¤¹fd¤Înone block flag¤ò¥ê¥»¥Ã¥È¤¹¤ë¤³¤È¤Ë¤è¤ê¤³¤ÎÌäÂê¤ËÂн补 + + connection_life_time¤ò¼ÂÁõ¤·¤¿¡¥ + + ¥í¥°¥á¥Ã¥»¡¼¥¸¤Ëpid¤¬ÉÕ¤¯¤è¤¦¤Ë¤·¤¿¡¥ + + max_pool¤ò±Û¤¨¤ÆÀܳ¤·¤¿¤È¤­¤Ë¥×¥í¥»¥¹¤¬exit¤·¤Æ¤·¤Þ¤¦¥Ð¥°¤ò½¤Àµ + ¤·¡¤¤³¤¦¤¤¤¦¤È¤­¤Ï"Sorry, too many clients already"¤òÊÖ¤¹¤è¤¦¤Ë + ¤·¤¿¡¥ + +0.1.2 (apapane) 2003/7/5(Sat) + + do_child()¤Ç¡¤¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬½ªÎ»¤·¤¿ºÝ¤Ë¥Õ¥í¥ó¥È¥¨¥ó¥É¤Ø¤Î¥³¥Í¥¯ + ¥·¥ç¥ó¤ò¥¯¥í¡¼¥º¤·¤Æ¤¤¤Ê¤¤¥ë¡¼¥È¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ¡¥ + + pool_get_cp()¤Ç¡¤¶õ¤­¥¹¥í¥Ã¥È¤òõ¤¹¥í¥¸¥Ã¥¯¤Ë¥Ð¥°¤¬¤¢¤Ã¤¿¤Î¤ò½¤Àµ¡¥ + + README¤Ëregression test, ¥Ù¥ó¥Á¥Þ¡¼¥¯¥Æ¥¹¥È¤ÎÊýË¡¤òµ­½Ò + +0.1.1 (amakihi) 2003/6/28(Sat) + + do_accept()¤Çaccept()¤Î°ú¿ô¤ò½é´ü²½¤·¤Æ¤¤¤Ê¤¤¥Ð¥°¤ò½¤Àµ + +0.1 (akohekohe) 2003/6/27(Fri) + + initial release + +Local Variables: +mode: outline +End: diff --git a/README b/README new file mode 100644 index 0000000..a82ec8a --- /dev/null +++ b/README @@ -0,0 +1,584 @@ +$Header$ + +pgpool version 2.5(kaku) README + +1. What is pgpool + + pgpool is a connection server for PostgreSQL. pgpool runs between + PostgreSQL's clients(front ends) and servers(back ends). A + PostgreSQL client can connect to pgpool as if it were a standard + PostgreSQL server. + + pgpool caches the connection to PostgreSQL server to reduce the + overhead to establish the connection to it. + + Also, pgpool could use two PostgreSQL servers for fail over. If the + first server goes down, pgpool will automatically switch to the + secondary server. + + Moreover, pgpool supports scheduled switch over. See + "9. Switchover" for more details. + +1.1 Anbout replication facility of pgpool + + pgpool could be used as a replication server. This allows real-time + backuping of the database to avoid disk failures. pgpool sends + exactly same query to each PostgreSQL servers to accomplish + replication. So pgpool can be regarded as a "synchronous + replication server". Currently pgpool supports up to 2 PostgreSQL + servers. + + Please note that some sort of quries such as random functions, OID, + XID, timestamp may not be replicated in exactly same value among + two servers. This is because qury results for these are local to + each PostgreSQL server. + + When one of PostgreSQL server goes down, pgpool tries to continue + serverce with live server. This is called "degeneration mode". + When you want to come back to the replication mode, please make + sure that the DB contens matche among two servers. The best way is + shutdown the live server and do a physical copy using rsync from + the live server to the dead server. Once the DB contents match you + start the two postmaster then restart pgpool. + +1.2 Avoiding deadlocks + + pgpool could send a query to the "master" server then send to + "secondary" server before master completes the query. This could + improve performace, there's a risk of deadlock however. To balance + the performace and risk, pgpool could operate in two modes. + + 1) "restrict" mode + + In this mode, pgpool wait for the completion of the master query + before sending a query to the secondary server. This is the safest + and default operating mode for pgpool. + + 2) using /*STRICT*/ keyword + + To achieve best performance, you could turn off the strict mode by + setting off to "pgpool_restrict" directive. To avoid deadlock, you + could insert a special keyword /*STRICT*/ in the beginning of each + deadlock-possible quries. Here is an example: + + /*STRICT*/ LOCK TABLE t1; + +1.3 what happens if a deadlock ocuurs? + + Since deadlocks mentioned above cannot be detected by PostgreSQL + itself, pgpool will abort the session if master or secondary does + not respond within certain period. The period can be changed by + setting replication_timeout directive. + +1.4 about load balancing mode + + If replication is enabled, you can enjoy the load balancing + capability of pgpool by enabling load_balance_mode in + pgpool.conf. If conditions below are all meet, SELECT queries are + distributed among the master and the slave server in random manner, + which will boost performance: + + 1) protocol version is V3. this means the backend must be + PostgreSQL 7.4 or later. + + 2) the query begins with "SELECT" or "select" (case is ignored). no + space is allowed before "SELECT". + + 3) SELECT query is not in a transatcion block. + + Please note that a SELECT may modify databases by calling a + updatable function. In this case you should NOT use the load + balancing. Othewise pgpool will fail due to the contents difference + between the master and the secondary database. You can avoid the + load balancing by putting spaces or comments in the begining of the + query. + + BTW, since the regression test includes such a SELECT (for example + "SELECT 'one' AS one, nextval('insert_seq');" in the constraints + test), the regression test will fail if the load balancing mode is + enabled. + +2. Advantages of pgpool + + There are some connection pool servers other than pgpool. This + section explains why you should use pgpool: + + 1) you do not need to modify your applications + + There are some connection pool servers which require special + API(Application Program Interface) to play with them. Since pgpool + looks like PostgreSQL server from the client's point of view, + existing PostgreSQL applications can be used without any + modifications. + + 2) any programming languages can be used + + Since pgpool is not an API, applications written in any languages + including PHP, Perl and Java can be used. + + 3) employing prefork architecture + + pgpool employing prefork architecture, meaning no need to start up + process for each connection from its clients, gives better + performance. + + 4) resource usage control + + pgpool can limit number of connections to PostgreSQL server. Users + could avoid too much load of PostgreSQL by using pgpool especially + under Web application environment. + + 5) fail over + + pgpool has a functionality so called "fail over". If the first + server goes down, pgpool will automatically switch to the secondary + server. + + 6) replication + + pgpool can be used as a replication server. + + 7) load balancing + + SELECT statement can be distributed among servers to gain more performance. + +3. Disadvantage of pgpool + + 1) overhead + + Any access to PostgreSQL must go through pgpool, which means some + overhead is added to each database access. In my testing using + pgbench shows 7 to 15% performance penalty. This number may + vary for each testing environment though. + + 2) not all libpq protocols are supported + + currently following protocols are not supported: + + o any authentication methods except "trust", "clear text password" + (replication mode) + + o any authentication methods except "trust", "clear text password", + "crypt", "md5" (non replication mode) + + 3) no access control to pgpool using pg_hba.conf + + Any client can connect to pgpool. If this is your concern, you + could limit access by using another software such as iptables. + +4. supported environments + + pgpool supports libpq protocol version 2(employed by PostgreSQL 6.4 + to 7.3). If you are going to use with PostgreSQL 7.2 or earlier, + you need to modify following line in pgpool.conf. + + 7.1 or earlier: + reset_query_list = 'ABORT' + + 7.2.x: + reset_query_list = 'ABORT, RESET ALL' + + 7.3 or later: + reset_query_list = 'ABORT, RESET ALL, SET SESSION AUTHORIZATION DEFAULT' + (currently the default value in pgpool.conf. so you don't need to + change it) + + Here are small lists from users where pgpool is running: + + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.5 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.3 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.2 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.3.7 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.3.6 + Vine Linux 2.6r3 (kernel 2.4.22-0vl2.8)/PostgreSQL 7.4.2 + Vine Linux 2.6r3 (kernel 2.4.22-0vl2.8)/PostgreSQL 7.3.6 + Vine Linux 2.6CR (kernel 2.4.20-0vl29.1)/PostgreSQL 7.3.4 + RedHat Linux 9.0 (kernel 2.4.20)/PostgreSQL 7.3.6 + RedHat Linux 8.0 (kernel 2.4.18-14)/PostgreSQL 7.3.2 + RedHat Linux 6.2 (kernel 2.2.24)/PostgreSQL 7.2.1 + FreeBSD 5.2.1-RELEASE(AMD64)/PostgreSQL 7.4.3 + FreeBSD 5.2.1-RELEASE/PostgreSQL 7.3? + FreeBSD 4.7-RELEASE/PostgreSQL 7.2.4 + FreeBSD 4.2-RELEASE/PostgreSQL 7.3.2 + Sparc/Solaris8/PostgreSQL 7.3 + Sparc/Solaris8/PostgreSQL 7.4.3 + +5. How to install pgpool + + ./configure + make + make install + + of course "make" should be read as "gmake" if you are using + FreeBSD or Solaris. + + Default installation directories are: + + /usr/local/bin/pgpool pgpool executable + /usr/local/etc/pgpool.conf.sample example configuration file + + You could change the installation directory by giving --prefix + option to configure: + + configure --prefix=path... + +6. Setting up pgpool.conf + + pgpool.conf is the configuration file for pgpool. + + Copy pgpool.conf.sample as pgpool.conf and change it if neccessary. + + Here is a explanation of pgpool.conf's grammar. + + 1) configuration variables can be set by: + + item = value + + pair. + + 2) if the value is a numeric, just write numerics. If the value is + a string, you need to quote using single quote pair. example: + + 'foo' + + 3) empty lines are ignored + + 4) lines starting with # are ignored. + + + Here is a list of existing items: + + listen_addresses + + Specifies the addresses to listen on for TCP/IP connections. Set + to '*' for all configured IP interfaces, '' for no TCP/IP + connections, or else to a specific IP address or host name. The + default is 'localhost'. Note that connections via UNIX domain + sockets are always allowed. + + (For compatibility with earlier versions of pgpool, + allow_inet_domain_socket = 1 means listen_addresses = '*' and + allow_inet_domain_socket = 0 means listen_addresses = ''.) + + port + + the port number where pgpool is running on. Default value is 9999. + + backend_host_name + + the real PostgreSQL server name pgpool could connect. Default + value is '' (empty string), which means pgpool will connect via + UNIX domain sockets. Any string other than '' is considered as a + host name where the PostgreSQL server is running. In this case the + pg_hba.conf file must be properly set so that pgpool could connect + to. + + backend_port + + the port number where real PostgreSQL server is running on. Default + value is 5432. + + secondary_backend_host_name + + if you are going to use fail over or replication functionality of + pgpool, you need to set the hostname or ''. Default value is ''. + + secondary_backend_port + + if you are going to use fail over or replication functionality of + pgpool, you need to set the port number where PostgreSQL is running + on. Default value is 0, which means the fail over functionality is + disabled. + + num_init_children + + number of pgpool process initially forked. Default value is 32. + + max_pool + + number of connection pools each pgpool server process are keeping. + pgpool will make a new connection if there's no user name and + database name pair yet. Thus it is recommended that max_pool + exceeds the number of such that possible pairs. If it exceeds, the + oldest connection is discarded and the new connection uses the + slot. The default value is 4. + + note that the total number of connections to the PostgreSQL server + can be calculated by following: + + num_init_children*max_pool + + child_life_time + + Life of a idle child process in seconds. This will prevent unwanted + memory leaks or other problems. Default is 300. Set it to 0 + disables this feature. + + connection_life_time + + life time for each idle connection in seconds. 0 means the life + time is forever. The default value is 0. + + logdir + + the directory name to store pgpool's log files. Currently only a + file named pgpool.pid(has pgpool's process id) is stored. The + default value for logdir is '/tmp'. + + replication_mode + + set this true if you are going to use replication + functionality. Default is false. + + replication_strict + + If true, pgpool will wait for the completion of the master query + before sending a query to the secondary server. This is the safest + and default operating mode for pgpool. Default is true. + + replication_timeout + + In non strict replication mode, there will be a chance of + deadlock. pgpool will abort the session if master or secondary does + not respond within this milli seconds. if set to 0, timeout is + disabled. + + load_balance_mode + + Perform load balancing for SELECT. Default is false. + + weight_master + weight_secondary + + load balance weight for master and secondary. actual weight is + calculated by weight_master:weight_secondary. For example both + + weight_master = 10 and weight_secondary = 5 + weight_master = 4 and weight_secondary = 2 + + are regarded as master has double the weight comparing with + secondary. master and secondary have same weight in the default. + + replication_stop_on_mismatch + + Stop replication mode on data mismatch between master and + secondary. Default is false. + + reset_query_list + + semicolon separated SQL commands to be issued at the end of + session. Default is as following: + + reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + You may add you own SQL commands to the list. Please note that + above all queries may not be accepted by all PostgreSQL + versions(see "4. supported environmets" for more details). + + Note that "ABORT" will not be issued if the backend is 7.4 or later + and the session is not in a transaction block. + + print_timestamp + + If true timestamp is added to each log line. Default value is true. + + master_slave_mode + + Run in master/slave mode. See 14 for more details. Default value is + false. This mode is not compatible with replication_mode. + + connection_cache + + If true, cache connections to PostgreSQL. Default value is true. + + health_check_timeout + + pgpool does "health check" periodically to detect PostgreSQL + servers down, network communication problems or as such. If + something is going wrong, pgpool will automatically run into fail + over or degeneration mode. + + This parameter specifies the timeout value in seconds to avoid hung + up in the health checking. The default is 20. 0 means no timeout. + + The health checking actually connects to PostgreSQL as if it's an + ordinaly PostgreSQL client. Thus you may need to increase the + max_connections parameter of PostgreSQL. + + health_check_period + + Specifies the interval for next health checking. 0 means no health + checking. The default is 0(i.e. no health checking). + + health_check_user + + PostgreSQL user name for the health checking. + +7. Starting pgpool + + The simplist way to start pgpool is: + + $ pgpool + + pgpool will load /usr/local/etc/pgpool.conf. + + available options for pgpool are: + + -f path + + the path to the configuration file. + + -n + + do not start as daemon. Error messages go to stdout or stderr. Thus + you could play with utilities such as logger and rotatelogs. You + need to run in background explicitly if you use this option. + + -d + + lots of debugging messages come out + + -h + + print the help message and quit + +8. Stopping pgpool + + You can stop pgpool by using "stop" option: + + $ pgpool [-f config_file] -m {s[mart]|f[ast]|i[mmediate]} stop + + If there's any live connection from frontend, it will wait until + the connection terminated. + + To force it to be stopped, try: + + $ pgpool -m f[ast] stop + + or + + $ pgpool -m i[mmediate] stop + +9. switchover + + For maintenance purpose, scheduled switching or degenration is + supported. + + $ pgpool [-f config_file] [-s {m[aster]|s[econdary]] switch + + If [-m {s[mart]|f[ast]|i[mmediate]}] part is omitted, master goes + down. To stop secondary try: + + $ pgpool [-f config_file] -s s[econdary] switch + + Note that "s[econdary]" measn "s" or "secondary". + + If there's only one PostgreSQL server, pgpool switch will just + restart pgpool child processes. + +10. how to get logging + + You could save messages from pgpool to a file by starting it with + -n option: + + pgpool -n >& /tmp/pgpool.log & + + If you prefer to log to syslog, do like this: + + pgpool -n 2>&1 |logger -t pgpool -p local0.info& + +11. getting internal status of pgpool + + You could use psql or whatever to obtain the internal status of + pgpool by issuing a special SQL command: + + psql -p 9999 -c 'show pool_status' template1 + + item | value | description +------------------------------+------------------------------------------------------+------------------------------------------------------------------------ + listen_addresses | * | host name(s) or IP address(es) to listen to + port | 9999 | pgpool accepting port number + socket_dir | /tmp | pgpool socket directory + backend_host_name | | master backend host name + backend_port | 5432 | master backend port number + secondary_backend_host_name | | secondary backend host name + secondary_backend_port | 0 | secondary backend port number + num_init_children | 1 | # of children initially pre-forked + child_life_time | 300 | if idle for this seconds, child exits + connection_life_time | 0 | if idle for this seconds, connection closes + max_pool | 4 | max # of connection pool per child + logdir | /tmp | logging directory + backend_socket_dir | /tmp | Unix domain socket directory for the PostgreSQL server + replication_mode | 0 | non 0 if operating in replication mode + replication_strict | 1 | non 0 if operating in strict mode + replication_timeout | 5000 | if secondary does not respond in this milli seconds, abort the session + load_balance_mode | 0 | non 0 if operating in load balancing mode + weight_master | 1.000000 | weight of master + weight_secondary | 1.000000 | weight of secondary + replication_stop_on_mismatch | 0 | stop replication mode on fatal error + reset_query_list | ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT; | queries issued at the end of session + print_timestamp | 1 | if true print time stamp to each log line + master_slave_mode | 0 | if true, operate in master/slave mode + connection_cache | 1 | if true, cache connection pool + health_check_timeout | 20 | health check timeout + health_check_period | 0 | health check period + current_backend_host_name | | current master host name + current_backend_port | 5432 | current master port # + replication_enabled | 0 | non 0 if actually operating in replication mode + master_slave_enabled | 0 | non 0 if actually operating in master/slave + num_reset_queries | 3 | number of queries in reset_query_list +(31 rows) + +12. Playing with regression test + + $ cd /usr/local/src/postgresql-7.4.5/src/test/regress + $ make all + $ ./pg_regress --schedule=parallel_schedule --port=9999 + +13. Playing with benchmarking + + Here is a brief explanation how to play with benchmarking using pgbench/PHP/ab. + + Initialize the pgbench database. + + $ pgbench -i test + + Prepare PHP script. Here is an exmaple PHP script. + + + + run ab. + + $ /usr/local/apache/bin/ab -c 100 -n 1000 "http://localhost/bench.php" + +14. master/slave mode + + master/slave mode is designed to cope with master/slave replication + softwares, such as Slony-I. To enable this mode, you need to set + secondary host, and set true to master_slave_mode and + load_balance_mode. Depending on the kind of qureries, pgpool + operates as follows: + + 1) if all below are satisfies, quries sent to both master and + secondary with load balance manner. + + - PostgreSQL 7.4 or later + - the query begins with "SELECT"(case insensitive) + - not in a transaction block + + 2) in all other case, quries are sent to only master + diff --git a/README.euc_jp b/README.euc_jp new file mode 100644 index 0000000..1cfc1f6 --- /dev/null +++ b/README.euc_jp @@ -0,0 +1,801 @@ +$Header$ + +pgpool version 2.5(kaku) README + +1. pgpool¤È¤Ï + + pgpool¤Ï¡¤PostgreSQLÀìÍѤΤ¤¤ï¤æ¤ë¡Ö¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¡×¥µ¡¼¥Ð¤Ç¡¤ + PostgreSQL¥¯¥é¥¤¥¢¥ó¥È¤ÈPostgreSQL¥µ¡¼¥Ð¤Î´Ö¤Çξ¼Ô¤ÎÃçΩ¤Á¤ò¤·¤Þ¤¹¡¥ + pgpool¤òÍøÍѤ¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¤PostgreSQL¥µ¡¼¥Ð¤Ø¤ÎÀܳ¥ª¡¼¥Ð¥Ø¥Ã¥É + ¤òÄ㸺¤Ç¤­¡¤¥·¥¹¥Æ¥àÁ´ÂΤΥ¹¥ë¡¼¥×¥Ã¥È¤ò¸þ¾å¤µ¤»¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + PostgreSQL¤Î¥¯¥é¥¤¥¢¥ó¥È¤¬pgpool¤ËÀܳ¤¹¤ë¤È¡¤½é²ó¤ÏPostgreSQL¤Ø¤Î + Àܳ¤¬pgpool¤«¤é³ÎΩ¤µ¤ì¤Þ¤¹¡¥¥¯¥é¥¤¥¢¥ó¥È¤¬½ªÎ»¤·¤Æ¤âPostreSQL¤Ø¤Î + Àܳ¤ÏÀÚÃǤµ¤ì¤ë¤³¤È¤Ê¤¯»Ä¤ê¡¤¼¡²ó¤ÎƱ¤¸¥æ¡¼¥¶¡¤¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ç + pgpool¤Ø¤ÎÀܳ¤¬¤¢¤Ã¤¿¤È¤­¤Ë¤Ï¤³¤ÎPostgreSQL¤Ø¤ÎÀܳ¤¬ºÆÍøÍѤµ¤ì¤Þ + ¤¹¡¥ + + pgpool¤Ë¤Ï¾ã³²»þ¤Ë¡Ö¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡×(¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¥â¡¼¥É»þ)¤¢ + ¤ë¤¤¤Ï¡Ö½ÌÂ౿ž¡×¡Ê¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É»þ¡Ë¤Îµ¡Ç½¤¬¤¢¤ë¤Î¤Ç¡¤¥· + ¥¹¥Æ¥à¤Î¥À¥¦¥ó¥¿¥¤¥à¤òºÇ¾®¸Â¤Ë²¡¤µ¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä½ÌÂ౿ž¤Ï²¿¤«¾ã³²¤¬µ¯¤­¤¿¤³¤È¤ò¥È¥ê¥¬¤Ë¤·¤Æ + µ¯Æ°¤µ¤ì¤Þ¤¹¤¬¡¤¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¤Ê¤É¤Î¤¿¤á¤Ë°Õ¿ÞŪ¤Ë¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä + ½ÌÂ౿ž¥â¡¼¥É¤Ë°Ü¹Ô¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡¥¾ÜºÙ¤Ï¡Ö9. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð¡× + ¤ò¤´Í÷²¼¤µ¤¤¡¥ + +1.1 ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤Ä¤¤¤Æ + + ¹¹¤Ëpgpool¤Ï¡Ö¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¡×¤â²Äǽ¤Ç¤¹¡¥¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò»ÈÍÑ + ¤¹¤ë¤³¤È¤Ë¤è¤ê¡¤ÊªÍýŪ¤Ë2Âæ¤Î¥Ç¥£¥¹¥¯¤Ë¥ê¥¢¥ë¥¿¥¤¥à¤Ç¥Ï¡¼¥É¥Ç¥£¥¹¥¯ + ¤Î¥Ð¥Ã¥¯¥¢¥Ã¥×¤ò¼è¤ë¤³¤È¤¬¤Ç¤­¡¤ÊÒÊý¤Ë¥Ç¥£¥¹¥¯¾ã³²¤¬È¯À¸¤·¤Æ¤â±¿ÍÑ + ¤ò·Ñ³¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥pgpool¤Î¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ÏƱ¤¸Ì䤤¹ç¤ï¤» + ¤ò2Âæ¤Î¥µ¡¼¥Ð¤ËÁ÷¿®¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¹Ô¤¤¤Þ¤¹¤Î¤Ç¡¤¤¤¤ï¤æ¤ëƱ´ü¥ì¥×¥ê + ¥±¡¼¥·¥ç¥ó¤Î°ì¼ï¤È¤¤¤¦¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥¤Ê¤ª¡¤º£¤Î¤È¤³¤í¡¤¥ì¥×¥ê¥±¡¼ + ¥·¥ç¥ó¤Ï2Âæ¤Î¤ß¤Ç¡¤3Âæ°Ê¾å¤Î¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¤Ç¤­¤Þ¤»¤ó¡¥ + + ¤³¤Î¤è¤¦¤Ê¼ÂÁõ¤Ç¤¹¤Î¤Ç¡¤pgpool¤Ç¤ÏƱ¤¸Ì䤤¹ç¤ï¤»¤òÁ÷¤Ã¤Æ¤â°Û¤Ê¤ë·ë + ²Ì¤òÊÖ¤¹¤è¤¦¤Ê¥Ç¡¼¥¿¡¤¤¿¤È¤¨¤ÐÍð¿ô¤ä¥È¥é¥ó¥¶¥¯¥·¥ç¥óID¡¤OID¡¤SERIAL¡¤ + ¥·¡¼¥±¥ó¥¹¡¤CURRENT_TIMETSTAMP¤Î¤è¤¦¤Ê¤â¤Î¤Ë´Ø¤·¤Æ¤Ï¥ì¥×¥ê¥±¡¼¥·¥ç + ¥ó¤Ï¤·¤Þ¤¹¤¬¡¤2Âæ¤Î¥Û¥¹¥È¤Ç¤Þ¤Ã¤¿¤¯Æ±¤¸Ãͤ¬¥³¥Ô¡¼¤µ¤ì¤ëÊݾڤϤ¢¤ê¤Þ + ¤»¤ó¡¥ + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥óÃæ¤Ë¾ã³²¤¬È¯À¸¤¹¤ë¤È¡¤¼«Æ°Åª¤Ë½ÌÂ౿ž¤ò¹Ô¤¤¤Þ¤¹¡¥ + Îã¤ò¼¨¤·¤Þ¤¹¡¥º£¡¤ + + master¥µ¡¼¥Ð(backend_host_name, backend_port¤Ç»ØÄê) + secondary¥µ¡¼¥Ð(secondary_backend_host_name, secondary_backend_port¤Ç»ØÄê) + + ¤Î2Âæ¤Ç¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¹Ô¤Ã¤Æ¤¤¤¿¤È¤·¤Þ¤¹¡¥ + + 1) Àµ¾ï»þ + + master, secondary¤ËƱ°ì¤Î¥Ç¡¼¥¿¤¬¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤µ¤ì¤ë¡¥ + + 2) master¤Ë¾ã³²¤¬È¯À¸ + + master¤òÀÚ¤êÎ¥¤·¤Æsecondary¤Î¤ß¤Ç±¿ÍѤò·Ñ³ + + 3) secondary¤Ë¾ã³²¤¬È¯À¸ + + secondary¤òÀÚ¤êÎ¥¤·¤Æmaster¤Î¤ß¤Ç±¿ÍѤò·Ñ³ + + 4) master¤Èsecondary¤Î¥Ç¡¼¥¿ÉÔ°ìÃפò¸¡½Ð + + pgpool¤ÏÁ´Éô¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¤¬¡¤Í×½êÍ×½ê¤Çmaster¤Îsecondary¤Î¥Ç¡¼ + ¥¿¤¬°ìÃפ·¤Æ¤¤¤ë¤«¤É¤¦¤«¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¤¤Þ¤¹¡¥¤¿¤È¤¨¤Ð¡¤Æ±¤¸¥Æ¡¼ + ¥Ö¥ë¤Ê¤Î¤ËÎó¿ô¤¬°Û¤Ê¤ë¤è¤¦¤Ê¥±¡¼¥¹¤Ï¡¤°Û¾ï¤È¸«¤Ê¤µ¤ì¤Þ¤¹¡¥¤³¤Î¤è + ¤¦¤Ê°Û¾ï¤¬¸¡½Ð¤µ¤ì¤ë¤È¡¤secondary¤Î¤ß¤Ç±¿ÍѤò·Ñ³¤·¤Þ¤¹¡¥ + + ½ÌÂ౿ž¤ËÆþ¤ë¤È°Ê¸åmaster¤Èsecondary¤Î¥Ç¡¼¥¿¤Ï°ìÃפ·¤Ê¤¤¾õÂ֤ˤʤë + ²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¡¥ºÆÅÙ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó±¿Å¾¤ËÆþ¤ëÁ°¤Ë¡¤°ìöξ·Ï¤òÄä + »ß¤·¡¤rsync¤Ê¤É¤ò»È¤Ã¤Æ¼êư¤Ç¥Ç¡¼¥¿¥Ù¡¼¥¹¥¯¥é¥¹¥¿¤Î¾õÂÖ¤ò°ìÃפµ¤»¤Æ + ¤¯¤À¤µ¤¤¡¥¤³¤ÎºÝ¡¤¾ã³²¤Î¾õ¶·¤Ë¤è¤Ã¤Æ¤Ïɬ¤º¤·¤âmaster¦¤¬ºÇ¿·¤È¤Ï¸Â + ¤é¤Ê¤¤¤Î¤ÇÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡¥master¡¤secondary¤Î¤É¤Á¤é¤Ç½ÌÂ౿ž¤ò¤· + ¤Æ¤¤¤ë¤«¤Ï¡¤pgpool¤Ëpsql¤Ê¤É¤«¤é"show pool_status"¥³¥Þ¥ó¥É¤òÅꤲ¤ë + ¤³¤È¤Ç³Îǧ¤Ç¤­¤Þ¤¹(¾ÜºÙ¸å½Ò)¡¥ + +1.2 ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤ª¤±¤ëÀ©¸Â»ö¹à + + ¤Þ¤Ã¤¿¤¯Æ±¤¸Ì䤤¹ç¤ï¤»¤ò2¤Ä¤Î¥µ¡¼¥Ð¤Ëȯ¹Ô¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¥ì¥×¥ê¥±¡¼ + ¥·¥ç¥ó¤ò¹Ô¤¦pgpool¤Ç¤Ï¡¤Ã±ÂΤÎPostgreSQL¤Ç¤ÏȯÀ¸¤·¤Ê¤¤¥Ç¥Ã¥É¥í¥Ã¥¯ + ¾õÂÖ¤¬µ¯¤³¤êÆÀ¤Þ¤¹¡¥¤½¤ÎÍýͳ¤Ï¡¤pgpool¤Ç¤Ï¡¤Ì䤤¹ç¤ï¤»¤ò + + 1) Ì䤤¹ç¤ï¤»¤Î¥ê¥¯¥¨¥¹¥È¤ò master, secondary ¤Î½ç¤ËÅꤲ¤ë + + 2) ·ë²Ì¤ÎÂÔ¤Á¹ç¤ï¤»¤ò master, secondary ¤Î½ç¤Ë¹Ô¤¦ + + ¤È¤¤¤¦¤è¤¦¤Ë½èÍý¤¹¤ë¤«¤é¤Ç¤¹¡¥¥Ç¥Ã¥É¥í¥Ã¥¯¤ÎÎã¤ò¼¨¤·¤Þ¤¹¡¥¤³¤³¤Ç¤Ï¡¤ + + BEGIN; + LOCK TABLE t1; + END; + + ¤È¤¤¤¦Ã±½ã¤Ê¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ò¹Í¤¨¤Þ¤¹¡¥°Ê²¼¤Î¿Þ¤Ç¤Ï¡¤begin, end¤Ï + ¾Êά¤·¤Æ¤¤¤Þ¤¹¡¥¤Þ¤¿¡¤2¤Ä¤Î¥»¥Ã¥·¥ç¥ósession 0¤Èsession 1¤¬¿Ê¹Ô¤·¤Æ + ¤¤¤ë¤â¤Î¤È¤·¤Þ¤¹¡¥ + + master secondary + session 0 session 1 session 0 session 1 + ------------------------------------------------------ + lock + lock + lock + lock + ------------------------------------------------------ + + session1¤Îmaster¤Ïsession0¤Îmaster¤òÂÔ¤Á³¤±¤Þ¤¹¤¬¡¤°ìÊýsecondary¤Ë + ¤ª¤¤¤Æ¤Ï¡¤session1¤¬Àè¤Ë¥í¥Ã¥¯¤ò³ÍÆÀ¤·¤¿¤¿¤á¡¤session0¤¬session1¤ò + ÂÔ¤Á³¤±¤Æ¤¤¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ë¤·¤Æ¤ª¸ß¤¤¤Ë¤ª¸ß¤¤¤òÂÔ¤Á³¤±¤ë¥Ç¥Ã¥É¥í¥Ã + ¥¯¾õÂÖ¤¬È¯À¸¤·¤Þ¤¹¡¥ + + pgpool¤Ç¤Ï¡¤¤³¤ÎÌäÂê¤ËÂн褹¤ë¤¿¤á¡¤°Ê²¼¤Î2¤Ä¤ÎÊýË¡¤òÍѰդ·¤Æ¤¤¤Þ¤¹¡¥ + + 1) pgpool.conf¤Îreplication_strict¤òtrue¤Ë¤¹¤ë + + ¤³¤¦¤¹¤ë¤È¡¤¾ï¤Ësecondary¤Ïmaster¤ÎÌ䤤¹ç¤ï¤»½èÍý¤¬½ª¤ï¤Ã¤Æ¤«¤é + Ì䤤¹ç¤ï¤»¤ò½èÍý¤¹¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥¥Ç¥Ã¥É¥í¥Ã¥¯¤¬È¯À¸¤¹¤ë¶²¤ì¤Ï + ¤Ê¤¯¤Ê¤ê¤Þ¤¹¤¬¡¤master¤Èsecondary¤ÎÊÂÎó½èÍý¤¬¤Ç¤­¤Ê¤¯¤Ê¤ë¤¿¤á¡¤ + ¥Ñ¥Õ¥©¡¼¥Þ¥ó¥¹¤¬Íî¤Á¤ë²ÄǽÀ­¤¬¤¢¤ê¤Þ¤¹¤¬¡¤¤â¤Ã¤È¤â°ÂÁ´¤ÊÊýË¡¤Ç¤¹¡¥ + pgpool¤Ï¥Ç¥Õ¥©¥ë¥È¤Ç¤³¤Î¥â¡¼¥É¤Çưºî¤·¤Þ¤¹¡¥ + + 2) ¥Ç¥Ã¥É¥í¥Ã¥¯¤¬È¯À¸¤¹¤ë²ÄǽÀ­¤Î¤¢¤ëÌ䤤¹ç¤ï¤»¤ÎÀèÆ¬¤ËÆÃÊ̤ʥ­¡¼¥ï¡¼ + ¥É¡Ö/*STRICT*/¡×¤òÆþ¤ì¤ë + + ¤¿¤È¤¨¤Ð¾å¤ÎÎã¤Ç¸À¤¦¤È + + /*STRICT*/ LOCK TABLE t1; + + ¤È¤·¤Þ¤¹¡¥¤³¤¦¤¹¤ë¤È¡¤¤³¤ÎÌ䤤¹ç¤ï¤»¤À¤±¤Ïmaster¤Èsecondary¤¬Ê + Îó½èÍý¤·¤Ê¤¯¤Ê¤ë¤Î¤Ç¡¤¥Ç¥Ã¥É¥í¥Ã¥¯¤¬È¯À¸¤·¤Þ¤»¤ó¡¥/*STRICT*/¤¬µ­ + Æþ¤µ¤ì¤Æ¤¤¤Ê¤¤Â¾¤ÎÌ䤤¹ç¤ï¤»¤ÏÊÂÎó½èÍý¤µ¤ì¤ë¤Î¤Ç¡¤¸úΨ¤¬Îɤ¯¤Ê¤ê + ¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤PostgreSQL¤Ç¤Ï¡¤/*¤«¤é*/¤Þ¤Ç¤Ï¥³¥á¥ó¥È¤È¤·¤Æ°·¤ï¤ì¤ë¤Î¤Ç¡¤ + DB½èÍý¤Ë±Æ¶Á¤Ï¤¢¤ê¤Þ¤»¤ó¡¥ + +1.3 replication_timeout¤Ë¤Ä¤¤¤Æ + + Ëü¤¬°ì¥Ç¥Ã¥É¥í¥Ã¥¯¤¬È¯À¸¤·¤¿¤È¤­¤ËÈ÷¤¨¡¤replication_timeout¤òÀßÄꤹ + ¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥Ã±°Ì¤Ï¥ß¥êÉÃ(1/1000ÉÃ)¤Ç¤¹¡¥¤â¤·master¤Î½èÍý¤¬½ª + ¤ï¤Ã¤Æ¤«¤ésecondary¤¬replication_timeout°ÊÆâ¤Ë±þÅú¤òÊÖ¤µ¤Ê¤¤¾ì¹ç¤Ï¡¤ + ³ºÅö¥»¥Ã¥·¥ç¥ó¤ò¶¯À©½ªÎ»¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¥Ç¥Ã¥É¥í¥Ã¥¯¾õÂÖ¤ò²ò¾Ã¤·¤Þ + ¤¹¡¥ + + ¤Ê¤ª¡¤master¤ËÈæ¤Ù¡¤secondary¤ÎÀ­Ç½¤¬Ãø¤·¤¯Îô¤ë¾ì¹ç¤Ë¤Ïsecondary¤Î + ±þÅú¤¬Ã٤졤¥Ç¥Ã¥É¥í¥Ã¥¯¤Ç¤Ï¤Ê¤¤¤Î¤Ë¥¿¥¤¥à¥¢¥¦¥È¤Ë¤Ê¤ë¤³¤È¤¬¤¢¤ê¤Þ + ¤¹¡¥¤³¤Î¾ì¹ç¤ÏŬÅö¤Ëreplication_timeout¤òÂ礭¤¯¤¹¤ë¤«¡¤ + replication_strict¤òtrue ¤Ë¤·¤Þ¤¹¡¥ + + Ãí°Õ: replication_strict¤¬true¤Î¾ì¹ç¤Ë¤Ï¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ï̵»ë¤µ¤ì¤Þ + ¤¹¡¥ + +1.4 Éé²Ùʬ»¶(load balance)¤Ë¤Ä¤¤¤Æ + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤¬Í­¸ú¤Ê¾ì¹ç¡¤pgpool.conf¤Î"load_balance_mode"¤ò + true¤ËÀßÄꤹ¤ë¤³¤È¤Ë¤è¤êSELECTʸ¤ÎÉé²Ùʬ»¶¤¬²Äǽ¤Ç¤¹¡¥°Ê²¼¤Î¾ò·ï¤Î + ¤â¤È¤Ç¥é¥ó¥À¥à¤Ë¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ËSELECTʸ¤¬È¯¹Ô¤µ¤ì¡¤¸¡º÷À­Ç½¤Î + ¸þ¾å¤¬´üÂԤǤ­¤Þ¤¹¡¥ + + 1) ¥×¥í¥È¥³¥ë¥Ð¡¼¥¸¥ç¥ó¤¬V3¤Ç¤¢¤ë¤³¤È¡¥¤¹¤Ê¤ï¤Á¥Ð¥Ã¥¯¥¨¥ó¥É¤¬ + PostgreSQL 7.4°Ê¸å¤Ç¤¢¤ë¤³¤È + + 2) SQLʸ¤¬Àµ³Î¤Ë¹ÔƬ¤«¤éSELECT(¤¢¤ë¤¤¤Ïselect)¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤ë¤³¤È + + 3) SELECTʸ¤¬ÌÀ¼¨Åª¤Ê¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¥Ö¥í¥Ã¥¯Æâ¤Ç¼Â¹Ô¤µ¤ì¤Æ¤¤¤Ê¤¤¤³ + ¤È + + ¤Ê¤ª¡¤ÅöÁ³¤Î¤³¤È¤Ê¤¬¤é¹¹¿·¤òȼ¤¦´Ø¿ô¤ò¸Æ¤Ó½Ð¤¹¤è¤¦¤ÊÉûºîÍѤΤ¢¤ë + SELECTʸ¤ò»ÈÍѤ·¤Æ¤¤¤ë¾ì¹ç¤ÏÌäÂ꤬µ¯¤­¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ï + load_balance_mode"¤òfalse¤Ë¤¹¤ë¤«¡¤SELECTʸ¤Î¹ÔƬ¤Ë¥¹¥Ú¡¼¥¹¤ä + /*NO LOAD BALANCE*/¤Î¤è¤¦¤Ê¥³¥á¥ó¥È¤òÁÞÆþ¤·¤ÆÉé²Ùʬ»¶¤µ¤ì¤Ê¤¤¤è¤¦¤Ë + ¤·¤Æ¤¯¤À¤µ¤¤¡¥ + + ¤Á¤Ê¤ß¤Ë¡¤regression test¤Ë¤Ï¤½¤Î¤è¤¦¤ÊSELECTʸ¤¬´Þ¤Þ¤ì¤Æ¤¤¤ë¤¿¤á + (¤¿¤È¤¨¤Ðconstraints¥Æ¥¹¥È¤Î¡ÖSELECT 'one' AS one, + nextval('insert_seq');¡×)¥í¡¼¥É¥Ð¥é¥ó¥¹¥â¡¼¥É¤¬Í­¸ú¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤È + regression test¤¬Ä̤ê¤Þ¤»¤ó¡¥ + +2. pgpool¤Î¥á¥ê¥Ã¥È + + À¤¤ÎÃæ¤Ë¤Ïpgpool°Ê³°¤Ë¤â¥Ç¡¼¥¿¥Ù¡¼¥¹ÍѤΥ³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¥µ¡¼¥Ð¤¬ + ¸ºß¤·¤Þ¤¹¤¬¡¤¤½¤ì¤é¤ÈÈæ³Ó¤·¤¿¾ì¹ç¤Îpgpool¤Î¥á¥ê¥Ã¥È¤òÀâÌÀ¤·¤Þ¤¹¡¥ + + (1) ¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ÎÊѹ¹¤ÎɬÍפ¬¤¢¤ê¤Þ¤»¤ó + + ¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ëÍѤΥ½¥Õ¥È¤Ë¤ÏÀìÍÑ¤ÎÆÃÊ̤ÊAPI(¥¢¥×¥ê¥±¡¼¥·¥ç + ¥ó¥×¥í¥°¥é¥à¥¤¥ó¥¿¡¼¥Õ¥§¥¤¥¹)¤ò·Ðͳ¤·¤Ê¤¤¤ÈÍøÍѤǤ­¤Ê¤¤¤â¤Î¤â¤¢ + ¤ê¤Þ¤¹¤¬¡¤pgpool¤Ï¥¯¥é¥¤¥¢¥ó¥È¤«¤é¸«¤ë¤ÈÉáÄ̤ÎPostgreSQL¥µ¡¼¥Ð + ¤Ë¸«¤¨¤ë¤¿¤á¡¤¤½¤Î¤è¤¦¤ÊAPI¤ò»ÈÍѤ¹¤ëɬÍפ¬¤¢¤ê¤Þ¤»¤ó¡¥º£¤Þ¤Ç + PostgreSQL¤ò»È¤Ã¤Æ¤¤¤¿¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤Ï¡¤ÀܳÀè¤Î¥Ý¡¼¥ÈÈÖ¹æ¤ä + ¥Û¥¹¥È¤òÊѹ¹¤¹¤ë¤À¤±¤Ç¤¹¤°¤Ëpgpool¤¬ÍøÍѤǤ­¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥ + (¤¿¤À¤·¡¤¤¤¤¯¤Ä¤«À©¸Â»ö¹à¤¬¤¢¤ê¤Þ¤¹) + + (2) ¤É¤Î¸À¸ì¤Ç¤â»È¤¨¤Þ¤¹ + + pgpool¤ÏPostgreSQL¤Î¥¯¥é¥¤¥¢¥ó¥È¤ä¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤«¤é¸«¤ë¤ÈÉá + Ä̤ÎPostgreSQL¥µ¡¼¥Ð¤Ë¸«¤¨¤Þ¤¹¡¥¤·¤¿¤¬¤Ã¤ÆPHP, Perl, Java¤Ê¤É + ³Æ¸À¸ìÍѤÎPostgreSQLÍÑAPI¤¬¤½¤Î¤Þ¤Þ»È¤¨¤Þ¤¹¡¥ + + (3) prefork·¿¥¢¡¼¥­¥Æ¥¯¥Á¥ã + + Apache¤Ê¤É¤ÈƱÍÍ¡¤¤¢¤é¤«¤¸¤á¥µ¡¼¥Ð¥×¥í¥»¥¹¤òfork¤·¤Æ¤ª¤¯¥¢¡¼¥­ + ¥Æ¥¯¥Á¥ã¤òºÎÍÑ¡¥¥³¥Í¥¯¥·¥ç¥óÍ×µá¤ÎÅ٤˥µ¡¼¥Ð¥×¥í¥»¥¹¤òfork¤¹¤ë + Êý¼°¤ËÈæ¤Ù¡¤¥ª¡¼¥Ð¥Ø¥Ã¥É¤¬¾¯¤Ê¤¯¡¤±þÅúÀ­¤¬Í¥¤ì¤Æ¤¤¤Þ¤¹¡¥ + + (4) PostgreSQL¤Ø¤ÎÀܳ¿ô¤ÎÀ©¸Â¤¬²Äǽ + + PHP¤«¤éPostgreSQL¤Ë¥¢¥¯¥»¥¹¤¹¤ë¾ì¹ç¡¤Æ±»þÀܳ¿ô¤¬Apache¥µ¡¼¥Ð¤Î + ¥×¥í¥»¥¹¿ô¤ÈÅù¤·¤¯¤Ê¤ë¤¿¤á¡¤PostgreSQL¤¬²áÉé²Ù¤Ë¤Ê¤ê¤¬¤Á¤Ç¤¹¡¥ + pgpool¤Ç¤ÏPostgreSQL¤Ø¤ÎÀܳ¿ô¤Ïprefork¤·¤¿pgpool¤Î¥µ¡¼¥Ð¿ô¤Ë + ¤è¤Ã¤ÆÀ©¸Â¤µ¤ì¤ë¤¿¤á¡¤PostgreSQL¤¬¤â¤Ã¤È¤â¸úΨÎɤ¯Æ°ºî¤¹¤ëƱ»þ + Àܳ¿ô¤ò°Ý»ý¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + (5) ¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼µ¡Ç½¤òÁõÈ÷ + + pgpool¤Ë¤Ï¡Ö¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼¡×¤Îµ¡Ç½¤¬¤¢¤ê¤Þ¤¹¡¥¤¹¤Ê¤ï¤Á¡¤ + PostgreSQL¥µ¡¼¥Ð¤ò2Âæ»ØÄꤷ¤Æ¤ª¤­¡¤1Âæ¤¬¥À¥¦¥ó¤·¤¿ºÝ¤Ë¼«Æ°Åª¤Ë2 + ÂæÌܤΥµ¡¼¥Ð¤ËÀÚ¤êÂØ¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼µ¡Ç½¤Ë + ¤è¤ê¡¤¥·¥¹¥Æ¥à¤Î¥À¥¦¥ó¥¿¥¤¥à¤òºÇ¾®¸Â¤Ë²¡¤µ¤¨¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + ¤¿¤À¤·¡¤2Âæ¤ÎPostgreSQL¥µ¡¼¥Ð¤Î¥Ç¡¼¥¿¤òƱ´ü¤µ¤»¤ëµ¡Ç½¤Ï¤¢¤ê¤Þ¤» + ¤ó¤Î¤Ç¡¤É¬Íפʤé¤Ðdbmirror¤Ê¤É¤Î¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥Ñ¥Ã¥±¡¼¥¸¤òÊ» + ÍѤ·¤Æ¤¯¤À¤µ¤¤¡¥ + + ¤Þ¤¿¡¤¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼¤ÎºÝ¤Ë¤Ï¥¯¥é¥¤¥¢¥ó¥È¤È¤Î¥³¥Í¥¯¥·¥ç¥ó¤¬ÀÚ + ÃǤµ¤ì¤Þ¤¹¡¥¤·¤¿¤¬¤Ã¤Æ¡¤¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼¸å¤Ï¥¯¥é¥¤¥¢¥ó¥È¤ÏºÆÅÙ + pgpool¤ËÀܳ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥ + + (6) ¥ì¥×¥ê¥±¡¼¥·¥ç¥óµ¡Ç½¤òÁõÈ÷¡¥¥é¡¼¥¸¥ª¥Ö¥¸¥§¥¯¥È¤Î¥ì¥×¥ê¥±¡¼¥·¥ç + ¥ó¤â²Äǽ¤Ç¤¹¡¥ + + (7) Éé²Ùʬ»¶µ¡Ç½¤òÁõÈ÷¡¥SELECTʸ¤ÎÉé²Ùʬ»¶¤¬¤Ç¤­¤Þ¤¹¡¥ + +3. pgpool¤Î¥Ç¥á¥ê¥Ã¥È + + (1) ¥ª¡¼¥Ð¥Ø¥Ã¥É¤¬¤¢¤ê¤Þ¤¹ + + PostgreSQL¤ËÂФ¹¤ë¥¢¥¯¥»¥¹¤Ï¤¹¤Ù¤Æ¤¤¤Ã¤¿¤ópgpool¤ò·Ðͳ¤¹¤ë¤¿¤á¡¤ + ¤½¤Îʬ¤Î¥ª¡¼¥Ð¥Ø¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¡¥¥ª¡¼¥Ð¥Ø¥Ã¥É¤ÎÎ̤Ͼò·ï¤Ë¤è¤Ã¤Æ + °Û¤Ê¤ë¤Î¤Ç°ì³µ¤Ë¤Ï¸À¤¨¤Þ¤»¤ó¤¬¡¤»ä¤¬pgbench¤Ç»î¤·¤¿¸Â¤ê¤Ç¤Ï7- + 15%ÄøÅÙ¤ÎÀ­Ç½Îô²½¤¬Ç§¤á¤é¤ì¤Þ¤·¤¿¡¥ + + (2) ¤¹¤Ù¤Æ¤Îlibpq¥×¥í¥È¥³¥ë¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó + + ¸½»þÅÀ¤Ç¤Ï¡¤°Ê²¼¤Îµ¡Ç½¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤»¤ó¡¥ + + o trust, clear text password°Ê³°¤Îǧ¾ÚÊý¼°(¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼ + ¥É»þ) + + o trust, clear text password, crypt, md5°Ê³°¤Îǧ¾ÚÊý¼°(Èó¥ì¥×¥ê + ¥±¡¼¥·¥ç¥ó¥â¡¼¥É»þ) + + o pgpool¤ËÂФ·¤Æ¡¤pg_hba.conf¤Ë¤è¤ë¥¢¥¯¥»¥¹À©¸æ¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Æ + ¤¤¤Þ¤»¤ó(pgpool¤¬Àܳ¤¹¤ëPostgreSQL¤Ç¤Ï¤â¤Á¤í¤ópg_hba.conf¤Ë + ¤è¤ë¥¢¥¯¥»¥¹À©¸æ¤¬Í­¸ú¤Ë¤Ê¤ê¤Þ¤¹) + + (3) pgpool¼«ÂΤËpg_hba.conf¤Ë¤è¤ë¥¢¥¯¥»¥¹À©¸Â¤Ï¤«¤«¤ê¤Þ¤»¤ó + + TCP/IP¥³¥Í¥¯¥·¥ç¥ó¤òµö²Ä¤·¤Æ¤¤¤ë¾ì¹ç(¸å½Ò¤Î + allow_inet_domain_socket¤¬1¤Î¾ì¹ç)¡¤pgpool¼«ÂΤˤϤɤΥۥ¹¥È¤« + ¤é¤Ç¤âÀܳ¤Ç¤­¤Æ¤·¤Þ¤¤¤Þ¤¹¡¥É¬Íפʤé¤Ðiptables¤Ê¤É¤ò»È¤Ã¤Æ¥¢¥¯ + ¥»¥¹À©¸Â¤ò¤«¤±¤Æ²¼¤µ¤¤(¤â¤Á¤í¤ó¡¤pgpool¤¬Àܳ¤¹¤ëPostgreSQL¥µ¡¼ + ¥Ð¤Ç¤Ïpg_hba.conf¤Ë¤è¤ë¥¢¥¯¥»¥¹À©¸Â¤¬Í­¸ú¤Ç¤¹)¡¥ + + (5) À©¸Â»ö¹à + + o ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤ª¤±¤ëÀ©¸Â»ö¹à¤Ë¤Ä¤¤¤Æ¤Ï1.2¤ò¤´Í÷²¼¤µ¤¤¡¥ + + o template1, regression¤È¤¤¤¦Ì¾Á°¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ï¥³¥Í¥¯¥·¥ç¥ó¥×¡¼ + ¥ë¤ÎÂоݤˤʤê¤Þ¤»¤ó¡¥ + + o CREATE TEMP TABLE¤ÇºîÀ®¤µ¤ì¤¿¥Æ¡¼¥Ö¥ë¤Ï¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬¥»¥Ã¥·¥ç + ¥ó¤ò½ªÎ»¤·¤Æ¤âºï½ü¤µ¤ì¤Þ¤»¤ó¡¥¤³¤ì¤Ï¡¤¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¤Î¸ú + ²Ì¤Ç¥Ð¥Ã¥¯¥¨¥ó¥É¤«¤é¸«¤ë¤È¥»¥Ã¥·¥ç¥ó¤¬·Ñ³¤·¤Æ¤¤¤ë¤è¤¦¤Ë¸«¤¨ + ¤ë¤«¤é¤Ç¤¹¡¥¥»¥Ã¥·¥ç¥ó¤Î½ªÎ»»þ¤ËÌÀ¼¨Åª¤ËDROP TABLE¤¹¤ë¤«¡¤¥È + ¥é¥ó¥¶¥¯¥·¥ç¥ó¥Ö¥í¥Ã¥¯¤ÎÃæ¤ÇCREATE TEMP TABLE ... ON COMMIT + DROP¤ò¤ª»È¤¤²¼¤µ¤¤¡¥ + + o Ʊ¤¸Íýͳ¤ÇPREPARE¤ÇºîÀ®¤µ¤ì¤¿¥×¥é¥ó¤Ï¥»¥Ã¥·¥ç¥ó¤¬½ª¤ï¤Ã¤Æ¤âºï + ½ü¤µ¤ì¤Þ¤»¤ó¡¥DEALLOCATE¤ÇÌÀ¼¨Åª¤Ëºï½ü¤·¤Æ¤¯¤À¤µ¤¤¡¥ + +4. pgpool¤Î²ÔƯ´Ä¶­ + + pgpool¤Ï¡¤libpq¥×¥í¥È¥³¥ë¤Îversion 2(PostgreSQL 6.4-7.3.x¤ÇºÎÍÑ)¤ª + ¤è¤Óversion 3(PostgreSQL 7.4°Ê¹ß)¤ËÂбþ¤·¤Æ¤¤¤Þ¤¹¤¬¡¤¥»¥Ã¥·¥ç¥ó¤Î½ª + λ»þ¤ËÁ÷½Ð¤Ç¤­¤ëÌ䤤¹ç¤ï¤»¤Ë°ã¤¤¤¬¤¢¤ê¤Þ¤¹¡¥PostgreSQL¤Î¥Ð¡¼¥¸¥ç¥ó + ¤Ë±þ¤¸¤Æ°Ê²¼¤Î¤è¤¦¤Ëpgpool.conf¤òÀßÄꤷ¤Æ¤¯¤À¤µ¤¤¡¥ + + 7.1¤¢¤ë¤¤¤Ï¤½¤ì°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó: + reset_query_list = 'ABORT' + + 7.2.x: + reset_query_list = 'ABORT; RESET ALL' + + 7.3°Ê¹ß: + reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + ¤ËÊѤ¨¤Æ¤¯¤À¤µ¤¤(ºÇ¸å¤Ïpgpool.conf¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤʤΤǡ¤¼ÂºÝ¤Ë¤ÏÊÑ + ¹¹¤ÎɬÍפϤ¢¤ê¤Þ¤»¤ó)¡¥ + + version 2¥×¥í¥È¥³¥ë¤Èversion 3¤Î¥Õ¥í¥ó¥È¥¨¥ó¥É¤È¥Ð¥Ã¥¯¥¨¥ó¥É¤¬º®ºß + ¤·¤Æ¤¤¤Æ¤âÌäÂꤢ¤ê¤Þ¤»¤ó¡¥pgpool¤Ï¥×¥í¥È¥³¥ë¥Ð¡¼¥¸¥ç¥ó¤ò¼«Æ°È½Ê̤·¡¤ + ŬÀڤ˽èÍý¤·¤Þ¤¹¡Ê¤¿¤À¤·¡¤¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ÎPostgreSQL¤Î¥×¥í¥È¥³ + ¥ë¥Ð¡¼¥¸¥ç¥ó¤Ï¹ç¤ï¤»¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡Ë¡¥ + + Âбþ¤¹¤ëOS¤ÏÆÃ¤ËÀ©¸Â¤¬¤¢¤ê¤Þ¤»¤ó¡¥°Ê²¼¡¤Æ°ºî¤¬³Îǧ¤µ¤ì¤¿´Ä¶­¤Ç¤¹¡¥ + + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 8.0 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.5 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.3 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.4.2 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.3.7 + Vine Linux 2.6r4 (kernel 2.4.22-0vl2.12)/PostgreSQL 7.3.6 + Vine Linux 2.6r3 (kernel 2.4.22-0vl2.8)/PostgreSQL 7.4.2 + Vine Linux 2.6r3 (kernel 2.4.22-0vl2.8)/PostgreSQL 7.3.6 + Vine Linux 2.6CR (kernel 2.4.20-0vl29.1)/PostgreSQL 7.3.4 + RedHat Linux 9.0 (kernel 2.4.20)/PostgreSQL 7.3.6 + RedHat Linux 8.0 (kernel 2.4.18-14)/PostgreSQL 7.3.2 + RedHat Linux 6.2 (kernel 2.2.24)/PostgreSQL 7.2.1 + FreeBSD 5.2.1-RELEASE(AMD64)/PostgreSQL 7.4.3 + FreeBSD 5.2.1-RELEASE/PostgreSQL 7.3? + FreeBSD 4.7-RELEASE/PostgreSQL 7.2.4 + FreeBSD 4.2-RELEASE/PostgreSQL 7.3.2 + Sparc/Solaris8/PostgreSQL 7.3 + Sparc/Solaris8/PostgreSQL 7.4.3 + +5. pgpool¤Î¥¤¥ó¥¹¥È¡¼¥ëÊýË¡ + + (1) pgpool¤Î¥¤¥ó¥¹¥È¡¼¥ë + + ./configure + make + make install + + ¤Ç¥¤¥ó¥¹¥È¡¼¥ë¤¬´°Î»¤·¤Þ¤¹(GNU make¤¬É¬ÍפʤΤǡ¤FreeBSD¤Ê¤É¤Ç¤Ï + make¤ògmake¤ËÆÉ¤ßÂØ¤¨¤Æ¤¯¤À¤µ¤¤)¡¥¥Ç¥Õ¥©¥ë¥È¤Î¥¤¥ó¥¹¥È¡¼¥ëÀè¤Ï¡¤ + /usr/local°Ê²¼¤Ç°Ê²¼¤Î¤è¤¦¤Ê¥Õ¥¡¥¤¥ë¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Þ¤¹¡¥ + + /usr/local/bin/pgpool ¥×¥í¥°¥é¥àËÜÂÎ + /usr/local/etc/pgpool.conf.sample ÀßÄê¥Õ¥¡¥¤¥ë¥µ¥ó¥×¥ë + + ¥¤¥ó¥¹¥È¡¼¥ëÀè¤òÊѹ¹¤¹¤ë¾ì¹ç¤Ï¡¤configure --prefix=path... ¤È¤· + ¤Æ¤¯¤À¤µ¤¤¡¥ + +6. pgpool¤ÎÀßÄêÊýË¡ + + pgpool¤ÎÀßÄê¥Ñ¥é¥á¡¼¥¿¤Ïpgpool.conf¤ÇÀßÄꤷ¤Þ¤¹¡¥pgpool.conf.sample + ¤òpgpool.conf¤Ë¥³¥Ô¡¼¤·¡¤ÀßÄê¤ò¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡¥ + + pgpool.conf¤Î½ñ¼°¤Ï°Ê²¼¤Ç¤¹¡¥ + + (1) ÀßÄê¹àÌÜ = ÃÍ ¤Î¥Ú¥¢¤ÇÀßÄê¤ò¹Ô¤¤¤Þ¤¹¡¥ + + (2) Ãͤ¬¿ôÃͤξì¹ç¤Ï¤½¤Î¤Þ¤Þ¿ô»ú¤ò½ñ¤­¤Þ¤¹¤¬¡¤Ê¸»úÎó¤Î¾ì¹ç¤Ï¸¶Â§¤È + ¤·¤Æ'(ñ°ì°úÍÑÉä)¤Ç³ç¤ê¤Þ¤¹¡¥Îã:'foo' ¶õÇò¤¬´Þ¤Þ¤ì¤Ê¤¤¾ì¹ç¤Ïñ + °ì°úÍÑÉä¤ò¾Êά¤·¤Æ¤â¹½¤¤¤Þ¤»¤ó¡¥ÏÀÍýÃͤιàÌܤˤĤ¤¤Æ¤Ï¡¤true(¿¿)¡¤ + false(µ¶)¡¤1(¿¿)¡¤0(µ¶)¤Çµ­½Ò¤·¤Þ¤¹¡¥ + + (3) ¶õÇò¹Ô¤Ï̵»ë¤µ¤ì¤Þ¤¹¡¥ + + (4) ¹Ô¤ÎÀèÆ¬¤Ë"#"(¥·¥ã¡¼¥×)¤¬¤¢¤ë¹Ô¤Ï̵»ë¤µ¤ì¤Þ¤¹¡¥¥³¥á¥ó¥È¹Ô¤È¤·¤Æ + ¤ª»È¤¤²¼¤µ¤¤¡¥ + + pgpool.conf¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤ÊÀßÄê¹àÌܤ¬¤¢¤ê¤Þ¤¹¡¥ + + listen_address + + TCP/IP¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±ÉÕ¤±¤ë¥¢¥É¥ì¥¹¤ò¥Û¥¹¥È̾¤Þ¤¿¤ÏIP¥¢¥É¥ì¥¹¤Ç + »ØÄꤷ¤Þ¤¹¡¥¡Ö*¡×¤ò»ØÄꤹ¤ë¤È¤¹¤Ù¤Æ¤ÎIP¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤«¤é¤Î¥³¥Í¥¯¥·¥ç + ¥ó¤ò¼õ¤±ÉÕ¤±¤Þ¤¹¡¥¡Ö''¡×¤ò»ØÄꤹ¤ë¤ÈTCP/IP¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±ÉÕ¤±¤Þ + ¤»¤ó¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤϡÖlocalhost¡×¤Ç¤¹¡¥ + + UNIX¥É¥á¥¤¥ó¥½¥±¥Ã¥È·Ðͳ¤Î¥³¥Í¥¯¥·¥ç¥ó¤Ï¾ï¤Ë¼õ¤±ÉÕ¤±¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤°ÊÁ°¤Î¥Ð¡¼¥¸¥ç¥ó¤È¸ß´¹À­¤òÊݤĤ¿¤á¡¤allow_inet_domain_socket + ¥Ç¥£¥ì¥¯¥Æ¥£¥Ö¤ò»ÈÍѤ¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡¥ + + allow_inet_domain_socket = 1 ¤Ï¡¤ listen_addresses = '*' ¤ÈƱ¤¸¤Ç¡¤ + allow_inet_domain_socket = 0 ¤Ï listen_addresses = '' ¤ÈƱ¤¸¤Ç¤¹¡¥ + + port + + pgpool¤¬¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±ÉÕ¤±¤ë¥Ý¡¼¥ÈÈÖ¹æ¤Ç¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ9999 + ¤Ç¤¹¡¥ + + socket_dir + + pgpool¤¬¥³¥Í¥¯¥·¥ç¥ó¤ò¼õ¤±ÉÕ¤±¤ëUnix domain socket¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡¥ + ¥Ç¥Õ¥©¥ë¥ÈÃͤÏ'/tmp'¤Ç¤¹¡¥ + + backend_host_name + + pgpool¤¬Àܳ¤¹¤ëPostgreSQL¥µ¡¼¥Ð(postmaster)¤¬Æ°¤¤¤Æ¤¤¤ë¥Û¥¹¥È¤Î̾ + Á°(ʸ»úÎó)¤Ç¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ''¤Ç¡¤¤³¤Î¾ì¹çUNIX¥É¥á¥¤¥ó¥½¥±¥Ã¥È¤ò + Ä̤¸¤ÆÀܳ¤ò¹Ô¤¤¤Þ¤¹¡¥''°Ê³°¤Ê¤é¤Ð¥Û¥¹¥È̾¤È¸«¤Ê¤·¡¤INET¥É¥á¥¤¥ó¥½ + ¥±¥Ã¥È·Ðͳ¤ÇÀܳ¤·¤Þ¤¹¡¥¤³¤Î¾ì¹ç¡¤PostgreSQL¦¤Ç¤ÏTCP/IP¥³¥Í¥¯¥·¥ç + ¥ó¤ò¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ë¤³¤È¡¤¤Þ¤¿pg_hba.conf¤¬Å¬ÀÚ¤ËÀßÄꤵ¤ì + ¤Æ¤¤¤Æpgpool¤«¤é¤ÎÀܳ¤òµö²Ä¤¹¤ë¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤ëɬÍפ¬¤¢¤ê¤Þ¤¹ + ¡ÊPostgreSQL¤«¤é¸«¤ë¤È¡¤pgpool¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Ë¸«¤¨¤ë¤³¤È¤ò»×¤¤½Ð¤· + ¤Æ¤¯¤À¤µ¤¤¡¥¡Ë¡¥ + + backend_port + + PostgreSQL¥µ¡¼¥Ð¤Î¥Ý¡¼¥ÈÈÖ¹æ¤Ç¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5432¤Ç¤¹¡¥ + + backend_socket_dir + + PostgreSQL¥µ¡¼¥Ð¤ÎUnix domain socket¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ'/tmp'¤Ç¤¹¡¥ + + secondary_backend_host_name + + ¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼µ¡Ç½¤Þ¤¿¤Ï¥ì¥×¥ê¥±¡¼¥·¥ç¥óµ¡Ç½¤òÍøÍѤ¹¤ë¾ì¹ç¡¤2ÂæÌÜ + ¤ÎPostgreSQL¥µ¡¼¥Ð¤Î¥Û¥¹¥È̾¤ò»ØÄꤷ¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ''¤Ç¤¹¡¥ + + secondary_backend_port + + ¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¡¼µ¡Ç½¤Þ¤¿¤Ï¥ì¥×¥ê¥±¡¼¥·¥ç¥óµ¡Ç½¤òÍøÍѤ¹¤ë¾ì¹ç¡¤2ÂæÌÜ + ¤ÎPostgreSQL¥µ¡¼¥Ð¤Î¥Ý¡¼¥ÈÈÖ¹æ¤ò»ØÄꤷ¤Þ¤¹¡¥0¤ò»ØÄꤹ¤ë¤È¥Õ¥§¥¤¥ë¥ª¡¼ + ¥Ð¤·¤Þ¤»¤ó¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ0¤Ç¤¹¡¥ + + num_init_children + + prefork¤¹¤ëpgpool¤Î¥µ¡¼¥Ð¥×¥í¥»¥¹¤Î¿ô¤Ç¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ32¤Ë¤Ê¤Ã¤Æ + ¤¤¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤Ì䤤¹ç¤ï¤»¤Î¥­¥ã¥ó¥»¥ë¤ò¹Ô¤¦¤ÈÄ̾ï¤Î¥³¥Í¥¯¥·¥ç¥ó¤È¤ÏÊ̤˿·¤¿ + ¤Ê¥³¥Í¥¯¥·¥ç¥ó¤¬Ä¥¤é¤ì¤Þ¤¹¡¥¤·¤¿¤¬¤Ã¤Æ¡¤¤¹¤Ù¤Æ¤Î¥³¥Í¥¯¥·¥ç¥ó¤¬»ÈÍÑ + Ãæ¤Î¾ì¹ç¤ÏÌ䤤¹ç¤ï¤»¤Î¥­¥ã¥ó¥»¥ë¤¬¤Ç¤­¤Ê¤¯¤Ã¤Æ¤·¤Þ¤¦¤Î¤Ç¡¤¤´Ãí°Õ²¼ + ¤µ¤¤¡¥Ì䤤¹ç¤ï¤»¤Î¥­¥ã¥ó¥»¥ë¤òɬ¤ºÊݾڤ·¤¿¤¤¾ì¹ç¤Ï¡¤ÁÛÄꤵ¤ì¤ë¥³¥Í + ¥¯¥·¥ç¥ó¿ô¤ÎÇܤÎÃͤòÀßÄꤹ¤ë¤³¤È¤ò¤ª¤¹¤¹¤á¤·¤Þ¤¹¡¥ + + max_pool + + pgpool¤Î³Æ¥µ¡¼¥Ð¥×¥í¥»¥¹¤¬¥­¡¼¥×¤¹¤ëPostgreSQL¤Ø¤ÎºÇÂ祳¥Í¥¯¥·¥ç¥ó + ¿ô¤Ç¤¹¡¥pgpool¤Ï¡¤¥æ¡¼¥¶Ì¾¡¤¥Ç¡¼¥¿¥Ù¡¼¥¹¤¬Æ±¤¸¤Ê¤é¤Ð¥³¥Í¥¯¥·¥ç¥ó¤ò + ºÆÍøÍѤ·¤Þ¤¹¤¬¡¤¤½¤¦¤Ç¤Ê¤±¤ì¤Ð¿·¤¿¤ËPostgreSQL¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò³Î + Ω¤·¤è¤¦¤È¤·¤Þ¤¹¡¥¤·¤¿¤¬¤Ã¤Æ¡¤¤³¤³¤Ç¤ÏÁÛÄꤵ¤ì¤ë[¥æ¡¼¥¶Ì¾:¥Ç¡¼¥¿¥Ù¡¼ + ¥¹Ì¾]¤Î¥Ú¥¢¤Î¼ïÎà¤Î¿ô¤À¤±¤òmax_pool¤Ë»ØÄꤷ¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥¤â + ¤·max_pool¤ò»È¤¤¤­¤Ã¤Æ¤·¤Þ¤Ã¤¿¾ì¹ç¤Ï°ìÈָŤ¤¥³¥Í¥¯¥·¥ç¥ó¤òÀÚÃǤ·¡¤ + ¤½¤Î¥¹¥í¥Ã¥È¤¬ºÆÍøÍѤµ¤ì¤Þ¤¹¡¥ + + max_pool¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ4¤Ç¤¹¡¥ + + ¤Ê¤ª¡¤pgpoolÁ´ÂΤȤ·¤Æ¤Ï¡¤num_init_children*max_pool ʬ¤À¤± + PostgreSQL¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤¬Ä¥¤é¤ì¤ëÅÀ¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡¥ + + child_life_time + + pgpool¤Î»Ò¥×¥í¥»¥¹¤Î¼÷Ì¿¤Ç¤¹¡¥¥¢¥¤¥É¥ë¾õÂ֤ˤʤäƤ«¤é + child_life_timeÉ÷в᤹¤ë¤È¡¤°ìö½ªÎ»¤·¤Æ¿·¤·¤¤¥×¥í¥»¥¹¤òµ¯Æ°¤·¤Þ¤¹¡¥ + ¥á¥â¥ê¡¼¥ê¡¼¥¯¤½¤Î¾¤Î¾ã³²¤ËÈ÷¤¨¤¿Í½ËÉÁ¼Ã֤Ǥ¹¡¥child_life_time¤Î¥Ç + ¥Õ¥©¥ë¥ÈÃͤÏ300Éᤤ¹¤Ê¤ï¤Á5ʬ¤Ç¤¹¡¥0¤ò»ØÄꤹ¤ë¤È¤³¤Îµ¡Ç½¤ÏƯ¤­¤Þ¤» + ¤ó¡Ê¤¹¤Ê¤ï¤Áµ¯Æ°¤·¤ÃÊü¤·¡Ë¡¥¤Ê¤ª¡¤¤Þ¤À°ìÅ٤⥳¥Í¥¯¥·¥ç¥ó¤ò + ¼õ¤±ÉÕ¤±¤Æ¤¤¤Ê¤¤¥×¥í¥»¥¹¤Ë¤Ïchild_life_time¤ÏŬÍѤµ¤ì¤Þ¤»¤ó¡¥ + + connection_life_time + + ¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ëÃæ¤Î¥³¥Í¥¯¥·¥ç¥ó¤ÎÍ­¸ú´ü´Ö¤òÉÃñ°Ì¤Ç»ØÄꤷ¤Þ¤¹¡¥0 + ¤ò»ØÄꤹ¤ë¤ÈÍ­¸ú´ü´Ö¤Ï̵¸Â¤Ë¤Ê¤ê¤Þ¤¹¡¥connection_life_time¤Î¥Ç¥Õ¥© + ¥ë¥ÈÃͤÏ0¤Ç¤¹¡¥ + + logdir + + pgpool¤Î³Æ¼ï¥í¥°¥Õ¥¡¥¤¥ë¤ò³ÊǼ¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¹¡¥¸½ºß¤Î¤È¤³¤í¡¤ + pgpool.pid¤È¤¤¤¦¥×¥í¥»¥¹ID¤ò³ÊǼ¤¹¤ë¥Õ¥¡¥¤¥ë¤À¤±¤¬ºî¤é¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã + ¤Æ¤¤¤Þ¤¹¡¥logdir¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ'/tmp'¤Ç¤¹¡¥ + + replication_mode + + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Çưºî¤µ¤»¤ë¾ì¹ç¤Ïtrue¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡¥¥Ç + ¥Õ¥©¥ë¥ÈÃͤÏfalse¤Ç¤¹¡¥ + + replication_strict + + ¤³¤Î¥ª¥×¥·¥ç¥ó¤òtrue¤Ë¤¹¤ë¤È¡¤master¤ÎÌ䤤¹ç¤ï¤»½èÍý¤Î´°Î»¤òÂÔ¤Ã¤Æ + ¤«¤ésecondary¤Î½èÍý¤Ë°Ü¤ê¤Þ¤¹¡¥¥Ç¥Ã¥É¥í¥Ã¥¯¤Î´í¸±À­¤Ï¤Ê¤¯¤Ê¤ê¤Þ¤¹¤¬¡¤ + master¤Èsecondary¤Î´Ö¤ÇÌ䤤¹ç¤ï¤»¤ÎÊÂÎó½èÍý¤ò¹Ô¤ï¤Ê¤¯¤Ê¤ë¤Î¤ÇÀ­Ç½¤¬ + Äã²¼¤¹¤ë¾ì¹ç¤â¤¢¤ê¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤¤¹¤Ù¤Æ¤ÎÌ䤤¹ç¤ï¤»¤Ç¤Ï¤Ê¤¯¤Æ¡¤SQL¤Î¥³¥á¥ó¥È¤ò»È¤Ã¤Æ°ìÉô¤ÎÌ䤤 + ¹ç¤ï¤»¤Î¤ßstrictưºî¤µ¤»¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡¥¾ÜºÙ¤Ï1.2¤ò»²¾È¤·¤Æ¤¯¤À¤µ + ¤¤¡¥ + + ¤³¤Î¥ª¥×¥·¥ç¥ó¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏtrue¤Ç¤¹¡¥ + + replication_timeout + + replication_strict¤¬false¤Î¤È¤­¤Ë¥Ç¥Ã¥É¥í¥Ã¥¯¤ò´Æ»ë¤¹¤ë¤¿¤á¤Î¥¿¥¤¥à + ¥¢¥¦¥È»þ´Ö¤ò¥ß¥êÉÃñ°Ì¤Ç»ØÄꤷ¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏ5000¡¤¤¹¤Ê¤ï¤Á5Éà + ¤Ç¤¹¡¥0¤ò»ØÄꤹ¤ë¤È¥¿¥¤¥à¥¢¥¦¥È¤·¤Ê¤¯¤Ê¤ê¤Þ¤¹¡¥ + + load_balance_mode + + true¤ò»ØÄꤹ¤ë¤È¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤ÎºÝ¤Ë¡¤SELECTʸ¤ò¥Þ¥¹¥¿¤È¥» + ¥«¥ó¥À¥ê¤Î´Ö¤Ç¥í¡¼¥É¥Ð¥é¥ó¥¹¤·¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏfalse¤Ç¤¹¡¥ + + weight_master + weight_secondary + + ¥í¡¼¥É¥Ð¥é¥ó¥¹¥â¡¼¥É¤Î»þ¤Ë¡¤¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤ËSELECT¤ò¿¶¤êʬ¤±¤ë + ¡Ö½Å¤ß¡×¤òÄêµÁ¤·¤Þ¤¹¡¥¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Î¥Ï¡¼¥É¥¦¥§¥¢À­Ç½¤Ëº¹¤¬¤¢ + ¤ë¤È¤­¤ËÍ­ÍѤǤ¹¡¥ + + ½Å¤ß¤Ïweight_master¤Èweight_secondary¤ËÀßÄꤵ¤ì¤¿¿ôÃͤÎÈæÎ¨¤Ç·èÄꤵ + ¤ì¤Þ¤¹¡¥¤¿¤È¤¨¤Ð¡¤ + + weight_master = 0.5 + weight_secondary = 0.5 + + ¤ä + + weight_master = 1 + weight_secondary = 1 + + ¤Ï¤¤¤º¤ì¤â¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Î½Å¤ß¤¬Åù¤·¤¯¤Ê¤ê¤Þ¤¹¡Ê¥Ç¥Õ¥©¥ë¥È¤Ç¤¹¡Ë¡¥ + + weight_master = 1 + weight_secondary = 0.5 + + ¤Ê¤é¥Þ¥¹¥¿¤ÎÊý¤Ë¤Ï¥»¥«¥ó¥À¥ê¤Î2ÇܤγÎΨ¤ÇSELECT¤¬³ä¤ê¿¶¤é¤ì¤Þ¤¹¡¥ + + weight_master = 1 + weight_secondary = 0 + + ¤È¤¤¤¦ÀßÄê¤â²Äǽ¤Ç¡¤¤³¤Î¾ì¹ç¤Ï¥Þ¥¹¥¿¤À¤±¤ËSELECT¤¬³ä¤ê¿¶¤é¤ì¤ë¤è¤¦ + ¤Ë¤Ê¤ê¤Þ¤¹¡¥¤â¤Á¤í¤ó¡¤INSERT¤Ê¤É¤Î¹¹¿··Ï¤ÎÌ䤤¹ç¤ï¤»¤Ï¥Þ¥¹¥¿¤È¥»¥« + ¥ó¥À¥ê¤ÎξÊý¤Ë¾ï¤ËÅꤲ¤é¤ì¤Þ¤¹¡¥ + + replication_stop_on_mismatch + + true¤ò»ØÄꤹ¤ë¤È¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Î´Ö¤Ç¥Ç¡¼¥¿¤ÎÉÔ°ìÃפ¬¤¢¤Ã¤¿¾ì¹ç + ¤Ë¶¯À©Åª¤Ë½ÌÂ౿ž¤ËÆþ¤ê¤Þ¤¹¡¥¤³¤Î¥ª¥×¥·¥ç¥ó¤¬false¤Î¾ì¹ç¤Ï¡¤³ºÅö¤Î + Ì䤤¹ç¤ï¤»¤ò¶¯À©Åª¤Ë½ªÎ»¤¹¤ë¤À¤±¤Ëα¤á¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥ÈÃͤÏfalse¤Ç¤¹¡¥ + + reset_query_list + + ¥»¥Ã¥·¥ç¥ó¤¬½ªÎ»¤¹¤ë¤È¤­¤Ë¥³¥Í¥¯¥·¥ç¥ó¤ò½é´ü²½¤¹¤ë¤¿¤á¤ÎSQL¥³¥Þ¥ó¥É + ¤ò¡Ö;¡×¤Ç¶èÀڤäÆÎóµó¤·¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥È¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¤ + Ǥ°Õ¤ÎSQLʸ¤òÄɲ䷤Ƥ⹽¤¤¤Þ¤»¤ó¡¥ + + reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + + PostgreSQL¤Î¥Ð¡¼¥¸¥ç¥ó¤Ë¤è¤Ã¤Æ»ÈÍѤǤ­¤ëSQL¥³¥Þ¥ó¥É¤¬°ã¤¦¤Î¤Ç¡¤ + PostgreSQL 7.3°ÊÁ°¤Ç¤ÏÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤(¡Ö4. pgpool¤Î²ÔƯ´Ä¶­¡×»²¾È)¡¥ + + ¤Ê¤ª¡¤¡ÖABORT¡×¤Ï¡¤PostgreSQL 7.4°Ê¾å¤Ç¤Ï¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¥Ö¥í¥Ã¥¯¤Î + Ãæ¤Ë¤¤¤Ê¤¤¾ì¹ç¤Ë¤Ïȯ¹Ô¤µ¤ì¤Þ¤»¤ó¡¥ + + print_timestamp + + true¤Ê¤é¤Ðpgpool¤Î¥í¥°¤Ë¥¿¥¤¥à¥¹¥¿¥ó¥×¤òÄɲä·¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥È¤Ï + true¤Ç¤¹¡¥ + + master_slave_mode + + true¤Ê¤é¤Ð¥Þ¥¹¥¿/¥¹¥ì¡¼¥Ö¥â¡¼¥É¤Çpgpool¤ò±¿Å¾¤·¤Þ¤¹¡¥¾ÜºÙ¤Ï14¤ò¸«¤Æ + ¤¯¤À¤µ¤¤¡¥¥Ç¥Õ¥©¥ë¥È¤Ïfalse¤Ç¤¹¡¥¤³¤Î¥â¡¼¥É¤Ïreplication_mode¤È¤Ïξ + Ω¤·¤Þ¤»¤ó¡¥ + + connection_cache + + true¤Ê¤é¥³¥Í¥¯¥·¥ç¥ó¤ò¥­¥ã¥Ã¥·¥å¤·¤Þ¤¹¡¥¥Ç¥Õ¥©¥ë¥È¤Ïtrue¤Ç¤¹¡¥ + + health_check_timeout + + pgpool¤Ï¥µ¡¼¥Ð¾ã³²¤ä¥Í¥Ã¥È¥ï¡¼¥¯¾ã³²¤ò¸¡ÃΤ¹¤ë¤¿¤á¤Ë¡¤Äê´üŪ¤Ë¥Ð¥Ã + ¥¯¥¨¥ó¥É¤ËÀܳ¤ò»î¤ß¤Þ¤¹¡¥¤³¤ì¤ò¡Ö¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¡×¤È¸À¤¤¤Þ¤¹¡¥¾ã³² + ¤¬¸¡ÃΤµ¤ì¤ë¤È¡¤¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä½ÌÂ౿ž¤ò»î¤ß¤Þ¤¹¡¥ + + ¤³¤Î ¥Ñ¥é¥á¡¼¥¿¤Ï¡¤¥Í¥Ã¥È¥ï¡¼¥¯¥±¡¼¥Ö¥ë¤¬È´¤±¤¿ºÝ¤Ê¤É¤Ë¥Ø¥ë¥¹¥Á¥§¥Ã + ¥¯¤¬Ä¹»þ´ÖÂÔ¤¿¤µ¤ì¤ë¤Î¤òËɤ°¤¿¤á¤Î¥¿¥¤¥à¥¢¥¦¥ÈÃͤòÉÃñ°Ì¤Ç»ØÄꤷ¤Þ + ¤¹¡¥¥Ç¥Õ¥©¥ë¥È¤Ï20ÉäǤ¹¡¥0¤ò»ØÄꤹ¤ë¤È¥¿¥¤¥à¥¢¥¦¥È½èÍý¤ò¤·¤Þ¤»¤ó¡¥ + + ¤Ê¤ª¡¤¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤òÍ­¸ú¤Ë¤¹¤ë¤È¡¤¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤Î¤¿¤á¤Î;ʬ¤ÎÀÜ + ³¤¬1¤ÄɬÍפˤʤê¤Þ¤¹¤Î¤Ç¡¤PostgreSQL¤Îpostgresql.conf¤ÎÀßÄê¹àÌܤΠ+ max_connections¤ò¾¯¤¯¤È¤â1Áý¤ä¤¹¤è¤¦¤Ë¤·¤Æ¤¯¤À¤µ¤¤¡¥ + + health_check_period + + ¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤ò¹Ô¤¦´Ö³Ö¤òÉÃñ°Ì¤Ç»ØÄꤷ¤Þ¤¹¡¥0¤ò»ØÄꤹ¤ë¤È¥Ø¥ë¥¹ + ¥Á¥§¥Ã¥¯¤ò¹Ô¤¤¤Þ¤»¤ó¡¥¥Ç¥Õ¥©¥ë¥È¤Ï0¤Ç¤¹(¤Ä¤Þ¤ê¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤ò¹Ô¤¤ + ¤Þ¤»¤ó)¡¥ + + health_check_user + + ¥Ø¥ë¥¹¥Á¥§¥Ã¥¯¤ò¹Ô¤¦¤¿¤á¤ÎPostgreSQL¥æ¡¼¥¶Ì¾¤Ç¤¹¡¥ + +7. pgpool¤Îµ¯Æ° + + pgpool¤òµ¯Æ°¤¹¤ë¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤Ï¡¤ + + $ pgpool + + ¤È¤¹¤ë¤À¤±¤Ç¤¹¡¥¤³¤ì¤Ç/usr/local/etc/pgpool.conf¤òÆÉ¤ß¹þ¤ß¡¤¤½¤ÎÀß + Äê¤Ç¥µ¡¼¥Ð¤òµ¯Æ°¤·¤Þ¤¹¡¥ + + »ØÄê²Äǽ¤Ê¥ª¥×¥·¥ç¥ó¤Ï¼¡¤ÎÄ̤ê¤Ç¤¹¡¥ + + -f path + + ¥Ç¥Õ¥©¥ë¥È°Ê³°¤Î¥³¥ó¥Õ¥£¥®¥å¥ì¡¼¥·¥ç¥ó¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹Ì¾¤ò»ØÄꤷ¤Þ¤¹¡¥ + + -n + + ¥Ç¡¼¥â¥ó¥â¡¼¥É¤Çµ¯Æ°¤·¤Þ¤»¤ó¡¥¤³¤Î¥ª¥×¥·¥ç¥ó¤Ïlogger¤ärotatelogs¤Ê + ¤É¤ò»È¤Ã¤Æ¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¤ò¥Õ¥¡¥¤¥ë¤Ë½ÐÎϤ¹¤ë¤È¤­¤Ê¤É¤ËÊØÍø¤Ç¤¹¡¥ + + -d + + ¥Ç¥Ð¥Ã¥°¥á¥Ã¥»¡¼¥¸¤òÂçÎ̤˽ÐÎϤ·¤Þ¤¹¡¥ + + -h + + ¥Ø¥ë¥×¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ·¤Æ½ªÎ»¤·¤Þ¤¹¡¥ + +8. pgpool¤Î½ªÎ» + + ¡Östop¡×¥ª¥×¥·¥ç¥ó¤ò»È¤¤¤Þ¤¹¡¥ + + $ pgpool [-f path_to_configuration_file][-m {s[mart]|f[ast]|i[mmediate]}] stop + + ¤ÇÄä»ß¤Ç¤­¤Þ¤¹¡¥µ¯Æ°»þ¤Ë-f¥ª¥×¥·¥ç¥ó¤ÇÀßÄê¥Õ¥¡¥¤¥ë¤ò¤·¤Æ¤¤¤ë¤È¤­¤Ï¡¤ + stop»þ¤Ë¤â-f¥ª¥×¥·¥ç¥ó¤ÇÀßÄê¥Õ¥¡¥¤¥ë¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡¥ + + ¤Þ¤À¥Õ¥í¥ó¥È¥¨¥ó¥É¤«¤é¤ÎÀܳ¤¬½ªÎ»¤·¤Æ¤¤¤Ê¤¤»Ò¥×¥í¥»¥¹¤¬¤¢¤ë¤È¡¤ + pgpool¤Ï½ªÎ»¤»¤º¤Ë¤½¤ÎÀܳ¤¬½ªÎ»¤¹¤ë¤Î¤òÂÔ¤Á¤Þ¤¹¡¥stop¥ê¥¯¥¨¥¹¥È¤¬ + ȯ¹Ô¤µ¤ì¤¿°Ê¸å¤Ï¡¤¿·¤¿¤Ë¥¯¥é¥¤¥¢¥ó¥È¤Ïpgpool¤ËÀܳ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Þ + ¤»¤ó¡¥ + + ÂÔ¤¿¤º¤Ë¶¯À©Åª¤Ë½ªÎ»¤µ¤»¤ë¤Ë¤Ï¡¤°Ê²¼¤Î¤è¤¦¤Ë¤·¤Þ¤¹¡¥ + + $ pgpool -m fast stop + + ¤Þ¤¿¤Ï + + $ pgpool -m immediate stop + + fast¤Ï"f"¡¤immediate¤Ï"i"¤È¾Êά¤¹¤ë¤³¤È¤â¤Ç¤­¤Þ¤¹¡¥¤Á¤Ê¤ß¤Ë¡¤ + + $ pgpool -m smart stop + + ¤Þ¤¿¤Ï + + $ pgpool -m s stop + + ¤È¤¹¤ë¤È¡¤pgpool stop¤ÈƱ¤¸Æ°ºî¤ò¤·¤Þ¤¹¡¥ + +9. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð + + ¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¤Ê¤É¤Î¤¿¤á¤Ë°Õ¿ÞŪ¤Ë¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä½ÌÂ౿ž¥â¡¼¥É¤Ë + °Ü¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + $ pgpool [-f config_file] [-s {m[aster]|s[econdary]] switch + + -s¥ª¥×¥·¥ç¥ó¤ò¾Êά¤¹¤ë¤È¡¤¥Þ¥¹¥¿Â¦¤òÍî¤È¤·¡¤¥»¥«¥ó¥À¥ê¤Ë¥Õ¥§¥¤¥ë¥ª¡¼ + ¥Ð(¥³¥Í¥¯¥·¥ç¥ó¥×¡¼¥ë¥â¡¼¥É¤Çưºî»þ)¤Þ¤¿¤Ï½ÌÂà(¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼ + ¥É¤Çưºî»þ)¤·¤Þ¤¹¡¥¥»¥«¥ó¥À¥ê¤òÍî¤È¤·¤¿¤¤¾ì¹ç¤Ï¡¤ + + $ pgpool [-f config_file] -s s[econdary] switch + + ¤È¤·¤Þ¤¹¡¥ + + ¤Ê¤ª¡¤PostgreSQL¥µ¡¼¥Ð¤¬1Âæ¤Î¾õÂÖ¤ÇÆ°¤¤¤Æ¤¤¤ë¾ì¹ç¤Ï¡¤¸½ºß¤Î¥¯¥é¥¤¥¢ + ¥ó¥È¤«¤épgpool¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¶¯À©Åª¤Ë°ìÅÙÀÚÃǤ·¡¤pgpool¤Î»Ò¥×¥í + ¥»¥¹¤¬ºÆµ¯Æ°¤µ¤ì¤Þ¤¹¡¥ + +10. ¥í¥°¤Î¼è¤êÊý + + pgpool¤ò-n¥ª¥×¥·¥ç¥óÉդǵ¯Æ°¤¹¤ë¤È¡¤stderr(ɸ½à¥¨¥é¡¼½ÐÎÏ)¤Ë¥¨¥é¡¼ + ¤ä½ÅÂç¤Ê¾ðÊó(¤¿¤È¤¨¤Ð¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤·¤¿¤è¤¦¤Ê¾ì¹ç)¤Ë´Ø¤¹¤ë¥á¥Ã¥»¡¼ + ¥¸¤¬½ÐÎϤµ¤ì¤Þ¤¹¡¥¤³¤Î¤Þ¤Þ¥Õ¥¡¥¤¥ë¤Ë¥ê¥À¥¤¥ì¥¯¥È¤¹¤ë¤³¤È¤Ë¤è¤ê¡¤ + pgpool¤Î¥í¥°¤ò¼è¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + [¼Â¹ÔÎã] + + pgpool -n >& /tmp/pgpool.log & + ¤Þ¤¿¤Ï + pgpool -n > /tmp/pgpool.log 2>&1 & + + ¤³¤Î¤È¤­¡¤print_timestamp¤òtrue¤Ë¤·¤Æ¤ª¤¯¤È¡¤¥¿¥¤¥à¥¹¥¿¥ó¥×¤¬¥í¥°¤Ë + Éղ䵤ì¤Þ¤¹(print_timestamp¤Ï¥Ç¥Õ¥©¥ë¥È¤Çtrue¤Ç¤¹)¡¥ + + ¤Þ¤¿¡¤logger¥³¥Þ¥ó¥É¤ò»È¤Ã¤Æsyslog¤Ë¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ¹¤ë¤Î¤â¤è¤¤Êý + Ë¡¤Ç¤¹¡¥ + + [¼Â¹ÔÎã] + + pgpool -n 2>&1 |logger -t pgpool -p local0.info& + + ¤³¤ì¤Ë¤è¤ê¡¤°Ê²¼¤Î¤è¤¦¤Ê¥á¥Ã¥»¡¼¥¸¤¬syslog¤Ë½ÐÎϤµ¤ì¤Þ¤¹¡¥ + + Apr 13 15:07:11 srapc1977 4·î 13 15:07:11 pgpool: log: pid 2038: starting failover from (5432) to (5433) + Apr 13 15:07:11 srapc1977 4·î 13 15:07:11 pgpool: log: pid 2038: failover from (5432) to (5433) done. + + +11. pgpool¤ÎÆâÉô¾ðÊó¤Î¼èÆÀ + + pgpool¤¬Ç§¼±¤·¤Æ¤¤¤ëÀßÄê¥Õ¥¡¥¤¥ë(pgpool.conf)¤ÎÆâÍÆ¤ä¡¤¸½ºß¤Î¥ì¥× + ¥ê¥±¡¼¥·¥ç¥ó¤Î¾õÂÖ¤òSQL¤òȯ¹Ô¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¼èÆÀ¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ + ¤¹¡¥¤¿¤È¤¨¤Ð¡¤º£pgpool¤¬Æ±¤¸¥Û¥¹¥È¤Î¥Ý¡¼¥È9999¤Çư¤¤¤Æ¤¤¤ë¤È¤¹¤ë¤È¡¤ + °Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ¾ðÊó¤ò¼èÆÀ¤Ç¤­¤Þ¤¹¡¥ + + psql -p 9999 -c 'show pool_status' template1 + + (¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾¤Ï²¿¤Ç¤â¤«¤Þ¤¤¤Þ¤»¤ó)¡¥ + + item | value | description +------------------------------+------------------------------------------------------+------------------------------------------------------------------------ + listen_addresses | * | host name(s) or IP address(es) to listen to + port | 9999 | pgpool accepting port number + socket_dir | /tmp | pgpool socket directory + backend_host_name | | master backend host name + backend_port | 5432 | master backend port number + secondary_backend_host_name | | secondary backend host name + secondary_backend_port | 0 | secondary backend port number + num_init_children | 1 | # of children initially pre-forked + child_life_time | 300 | if idle for this seconds, child exits + connection_life_time | 0 | if idle for this seconds, connection closes + max_pool | 4 | max # of connection pool per child + logdir | /tmp | logging directory + backend_socket_dir | /tmp | Unix domain socket directory for the PostgreSQL server + replication_mode | 0 | non 0 if operating in replication mode + replication_strict | 1 | non 0 if operating in strict mode + replication_timeout | 5000 | if secondary does not respond in this milli seconds, abort the session + load_balance_mode | 0 | non 0 if operating in load balancing mode + weight_master | 1.000000 | weight of master + weight_secondary | 1.000000 | weight of secondary + replication_stop_on_mismatch | 0 | stop replication mode on fatal error + reset_query_list | ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT; | queries issued at the end of session + print_timestamp | 1 | if true print time stamp to each log line + master_slave_mode | 0 | if true, operate in master/slave mode + connection_cache | 1 | if true, cache connection pool + health_check_timeout | 20 | health check timeout + health_check_period | 0 | health check period + current_backend_host_name | | current master host name + current_backend_port | 5432 | current master port # + replication_enabled | 0 | non 0 if actually operating in replication mode + master_slave_enabled | 0 | non 0 if actually operating in master/slave + num_reset_queries | 3 | number of queries in reset_query_list +(31 rows) + +12. regression test¤Î¼Â»Ü + + °Ê²¼¤Î¤è¤¦¤Ë¤·¤Æpgpool¤òÊ»ÍѤ·¤Æregression test¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥ + + $ cd /usr/local/src/postgresql-7.4.5/src/test/regress + $ make all + $ ./pg_regress --schedule=parallel_schedule --port=9999 + + Ãí°Õ: PostgreSQL 8.0¤Ç¤Ï¡¤src/test/regress°Ê²¼¤Ë¥Æ¥¹¥ÈÍѤΥơ¼¥Ö¥ë + ¥¹¥Ú¡¼¥¹¤òºî¤ë¤¿¤á¡¤Æ±¤¸¥Û¥¹¥È¾å¤Ë2¤Ä¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹¥¯¥é¥¹¥¿¤òºî¤ê¡¤ + ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Çregression test¤ò¤¹¤ë¤Èɬ¤ºtablespace¤Î¥Æ¥¹ + ¥È¤¬fail¤·¤Þ¤¹¤¬¡¤¤³¤ì¤Ï°Û¾ï¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥ + +13. ¥Ù¥ó¥Á¥Þ¡¼¥¯¤Î¼Â»Ü + + ¥Ù¥ó¥Á¥Þ¡¼¥¯¤ò¼Â»Ü¤¹¤ë¤Ë¤Ï¤¤¤í¤¤¤í¤ÊÊýË¡¤¬¤¢¤ê¤Þ¤¹¤¬¡¤¤³¤³¤Ç¤Ï + pgbench¤ÈPHP¤½¤ì¤Ëab¤ò»È¤Ã¤¿´Êñ¤ÊÊýË¡¤ò¤´¾Ò²ð¤·¤Þ¤¹¡¥ + + ¤Þ¤º¡¤¥Ù¥ó¥Á¥Þ¡¼¥¯¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò½é´ü²½¤·¤Þ¤¹¡¥ + + $ pgbench -i test + + ab¤òµ¯Æ°¤·¤Þ¤¹¡¥¥¿¡¼¥²¥Ã¥È¤È¤Ê¤ëPHP¥¹¥¯¥ê¥×¥È¤Ï¤³¤³¤Ç¤Ï°Ê²¼¤Î¤è¤¦¤Ê + ´Êñ¤Ê¤â¤Î¤ò»È¤¤¤Þ¤¹¡¥ + + + + $ /usr/local/apache/bin/ab -c 100 -n 1000 "http://localhost/bench.php" + +14. master/slave¥â¡¼¥É + +master/slave¥â¡¼¥É¤Ï¡¤Slony-I¤Î¤è¤¦¤Ê¡¤master/slave¼°¤Î¥ì¥×¥ê¥±¡¼¥·¥ç +¥ó¥½¥Õ¥È¤Ë¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¤Þ¤«¤»¤ë¥â¡¼¥É¤Ç¤¹¡¥¤³¤Î¥â¡¼¥É¤Ç»È¤¦¤¿¤á¤Ë +¤Ï¡¤¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤ÈƱ¤¸¤è¤¦¤Ë¡¤¥Þ¥¹¥¿¤È¥»¥«¥ó¥À¥ê¤Î¥Û¥¹¥È¾ðÊó +¤ò¥»¥Ã¥È¤·¡¤master_slave_mode¤Èload_balance_mode¤òtrue¤Ë¤·¤Þ¤¹¡¥¤³¤Î¤È +¤­¡¤Ì䤤¹ç¤ï¤»¤Ë¤è¤Ã¤Æ¥Þ¥¹¥¿¤À¤±¤ËÌ䤤¹ç¤ï¤»¤¬Á÷¤é¤ì¤ë¾ì¹ç¤È¡¤¥Þ¥¹¥¿¤È +¥»¥«¥ó¥À¥ê¤Î¤É¤Á¤é¤«¤Ë¥í¡¼¥É¥Ð¥é¥ó¥¹¤µ¤ì¤ÆÌ䤤¹ç¤ï¤»¤¬Á÷¤é¤ì¤ë¾ì¹ç¤¬¤¢ +¤ê¤Þ¤¹¡¥ + +1) °Ê²¼¤Î¾ò·ï¤¬¤¹¤Ù¤ÆËþ¤¿¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¡¤Ì䤤¹ç¤ï¤»¤Ï¥Þ¥¹¥¿¤È¥»¥«¥ó¥À + ¥ê¤ËÉé²Ùʬ»¶¤µ¤ì¤Þ¤¹¡¥ + - PostgreSQL¤Î¥Ð¡¼¥¸¥ç¥ó¤¬7.4°Ê¹ß + - Ì䤤¹ç¤ï¤»¤¬Àµ³Î¤Ë"SELECT"(Âçʸ»ú/¾®Ê¸»ú¤ÎÊ̤Ï̵»ë¤µ¤ì¤Þ¤¹)¤Ç»Ï¤Þ¤Ã + ¤Æ¤¤¤ë + - Ì䤤¹ç¤ï¤»¤¬ÌÀ¼¨Åª¤Ê¥È¥é¥ó¥¯¥¶¥·¥ç¥ó¥Ö¥í¥Ã¥¯¤ÎÆâ¦¤Ë¤Ê¤¤(¤Ä¤Þ¤ê¡¤ + BEGIN¤òȯ¹Ô¤·¤Æ¤¤¤Ê¤¤) + +2) 1)°Ê³°¤Î¾ì¹ç¤Ï¡¤¥Þ¥¹¥¿¤À¤±¤ËÌ䤤¹ç¤ï¤»¤¬Á÷¤é¤ì¤Þ¤¹¡¥ diff --git a/TODO b/TODO new file mode 100644 index 0000000..de4de69 --- /dev/null +++ b/TODO @@ -0,0 +1,146 @@ +$Header$ + +TODO¹àÌÜ + +o ¥»¥Ã¥·¥ç¥ó³«»Ï»þ¤Ëȯ¹Ô¤¹¤ëÌ䤤¹ç¤ï¤»¤òpgpool.conf¤ÇÀßÄê²Äǽ¤Ë¤¹¤ë + +-o ¥»¥Ã¥·¥ç¥ó½ªÎ»»þ¤Ëȯ¹Ô¤¹¤ëÌ䤤¹ç¤ï¤»¤òpgpool.conf¤ÇÀßÄê²Äǽ¤Ë¤¹¤ë(v2.4)¡¥ + +-o Slony-IÂбþ(v2.5b2) + - ¥Þ¥¹¥¿Â¦¤Ï¤¹¤Ù¤Æ¤òÄ̤·¡¤¥»¥«¥ó¥À¥ê¦¤ÏSELECT¤Î¤ßÄ̤¹¡¥ + - ¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¥Ö¥í¥Ã¥¯¤Ï¥Þ¥¹¥¿Â¦¤Ë¤Î¤ßÄ̤¹¡¥ + - replication mode¤Ç¤Ê¤¯¤Æ¤âload balance¤¹¤ëmodeÄɲà + +-o no connection pooling mode(v2.5b2) + +-o schedule failover/½ÌÂà(v2.5b1) + - ñ¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë¤À¤± + +o 3Âæ°Ê¾å¤Î¥µ¡¼¥Ð¤ËÂбþ + +-o ¥¿¥¤¥à¥¹¥¿¥ó¥×¤Î°õ»úµ¡Ç½(v2.5b2) + +o query cache(regex ¤ÇÌ䤤¹ç¤ï¤»¤Î¥Ñ¥¿¡¼¥ó¤ä¥­¥ã¥Ã¥·¥åinvalidation»þ´Ö + ¤ÎÀßÄ꤬¤Ç¤­¤ë) + +o ´Æººµ¡Ç½ + +-o heart beat(v2.5b2) + +o ¥·¡¼¥±¥ó¥¹¤òreplication¤¹¤ë + - ¥·¡¼¥±¥ó¥¹½èÍý´Ø¿ô¤òÆþ¤ìÂØ¤¨¡¤Ãæ¤Ç¥í¥Ã¥¯¤¹¤ë¤è¤¦¤Ë¤¹¤ì¤ÐOK¤«¡©ÂÌÌÜ¡¥ + Íפϡ¤master¤Î¥í¥Ã¥¯¤¬secondary¤Înextval()¤¬½ª¤ï¤ë¤Þ¤ÇÂԤĤ褦¤Ë¤· + ¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤Î¤Ç¡¤¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¥Ö¥í¥Ã¥¯¤ÎÃæ¤Ë¤¤¤Ê¤±¤ì¤Ð¤Ê¤é + ¤Ê¤¤¡¥->¼«Æ°Åª¤Ë¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ò³«»Ï¤¹¤ì¤Ð¤è¤¤¡©¤É¤ÎÌ䤤¹ç¤ï¤»¤Î + ¤È¤­¤Ë¥È¥é¥ó¥¶¥¯¥·¥ç¥ó¤ò³«»Ï¤¹¤ë¤«È½ÃǤ¹¤ëɬÍפ¬¤¢¤ë¡¥->¥Ñ¡¼¥¹¥Ä¥ê¡¼ + ¤ò¼è¤Ã¤Æ¤¯¤ë¤«¡©->¤½¤³¤Þ¤Ç¤ä¤ê¤¿¤¯¤Ê¤¤¤¬¡¥DML¤À¤Ã¤¿¤é¼«Æ°¥¹¥¿¡¼¥È¡© + ¤Ç¤âSELECT nextval();¤Ê¤É¤Ï¤É¤¦¤¹¤ë¡©->ÌÀ¼¨Åª¤Ë¥·¡¼¥±¥ó¥¹¤ò°·¤Ã¤Æ + ¤¤¤ë¤³¤È¤ò»Ø¼¨¤µ¤»¤ë¤·¤«¤Ê¤¤¤«¡© + +o OID¤òreplication¤¹¤ë + +o °ì»þ¥Æ¡¼¥Ö¥ë¤òºï½ü¤¹¤ë´Ø¿ô¤òºî¤ë + +o ̵Ää»ß¥ê¥«¥Ð¥ê + 1) rsync + + 2) Ì䤤¹ç¤ï¤»½èÍýÃæ¤Ç¤Ê¤±¤ì¤Ð¡¤Ã±½ãSELECT°Ê³°¤Ï°ì»þŪ¤ËÌ䤤¹ç¤ï¤»¤ò + ÂÔ¤¿¤»¤ë¥â¡¼¥É¤Ë°Ü¹Ô->¤³¤ì¤Ç¤è¤¤¤«¡©XID¥«¥¦¥ó¥¿¤¬Æ±´ü¤·¤Ê¤¯¤Ê¤ë + ¤¬¡¥open transaction¤¬¤¢¤Ã¤¿¤é¥¢¥Ü¡¼¥È¤µ¤»¤ë->¤³¤Î¥±¡¼¥¹¤Ç¤Ï¥»¥Ã + ¥·¥ç¥ó¤ò½ªÎ»¤µ¤»¤ëɬÍפ¢¤ê¡© + + 3) CHECKPOINTȯ¹Ô + 4) rsync + 5) restart + 6) Ä̾ï¥â¡¼¥É¤Ë°Ü¹Ô->´û¸¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò°ú¤­·Ñ¤²¤ë¤«¡©SET¤ÇÀßÄꤷ¤¿ + ÃͤϤɤ¦¤¹¤ë¤«¡© + +-o ¥³¥Þ¥ó¥É°ú¿ô¤Î½èÍý + + -f config_file (default ¤Ï /usr/local/etc/pgpool.conf) + +-o UNIX domain/INET domainξÊý¤Î socket¤ËÂбþ¤¹¤ë + + ¥Ç¥Õ¥©¥ë¥È¤Ï Unix domain ¤Î¤ß¼õÉÕ¡¥config ¤Î inetdomain ¤¬ true ¤Ê¤é + ¤Ð¡¤INET domain ·Ðͳ¤ÎÀܳ¤â¼õ¤±ÉÕ¤±¤ë¡¥ + +-o ¥µ¡¼¥Ð¤Î¥Ç¡¼¥â¥ó²½ + +-o signal ¤Î¥Ö¥í¥Ã¥¯½èÍý + +-o SIGCHLD ¤Î¥Ï¥ó¥É¥é + +-o child ¿ô¤Î´ÉÍý¥¢¥ë¥´¥ê¥º¥à + + child ¿ô¤¬ num_min_children ¤ò²¼²ó¤Ã¤¿¤é num_init_children ¤Ë¤Ê¤ë¤Þ¤Ç + fork ¤¹¤ë + +-o child ¤Îtimeout½èÍý + +o child ¤Ï²Ë¤Ê¤È¤­¤Ë accept ¤·¤Æ¤ª¤¯(LRU ¥­¥å¡¼¤òºî¤ë)¡¥ + +o ¥¯¥é¥¤¥¢¥ó¥È¤¬ quit ¤·¤¿¤é¡¤LRU¥­¥å¡¼¤«¤é¼¡¤Î¥¯¥é¥¤¥¢¥ó¥È¤ò¼è¤ê½Ð¤¹ + ->child¤¬exit¤¹¤ë¤È¥­¥å¡¼¤ÎÃæ¿È¤¬¼º¤ï¤ì¤ë¤¬¡¤¤½¤ì¤Ç¤è¤¤¤«¡© + +-o TRUSTǧ¾Ú°Ê³°¤Ø¤ÎÂбþ + +-o ¥Ð¥Ã¥¯¥¨¥ó¥É¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤Ë timeout ¤òÉÕ¤±¤ë + +-o fail over + +-o replication + +-o load balancing + +-o ¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬¥³¥ß¥Ã¥È¤·¤Ê¤¤¤Þ¤Þexit¤¹¤ë¤È¡¤¤½¤ì¤ËÂбþ¤¹¤ë¥Ð¥Ã¥¯¥¨ + ¥ó¥É¤¬¥È¥é¥ó¥¶¥¯¥·¥ç¥ó´°Î»ÂÔ¤Á(:ERROR: current transaction is + aborted, queries ignored until end of transaction block)¤Ë¤Ê¤Ã¤Æ¤·¤Þ + ¤¦¡¥ + +-o µ¯Æ°¤¹¤ëÁ°¤Ëpid¥Õ¥¡¥¤¥ë¤Î¥Á¥§¥Ã¥¯¤ò¹Ô¤¦ + +-o configure¤ÇPostgreSQL include¥Ç¥£¥ì¥¯¥È¥ê¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤¹¤ë.¤È¤¤ + ¤¦¤«¡¤PostgreSQL¤Îinclude¥Õ¥¡¥¤¥ë¤ËÍê¤é¤Ê¤¤¤è¤¦¤Ë¤¹¤Ù¤­¡©->¤È¤ê¤¢¤¨ + ¤º --with-pgsql¤Ç»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¤·¤¿(6/24) + +-o template0, template1¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤(createdb¤¬ + ERROR: CREATE DATABASE: source database "template1" is being accessed + by other users¤Ë¤Ê¤ë)¡¥¤Þ¤¿¡¤regression¥Ç¡¼¥¿¥Ù¡¼¥¹¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó + ¤â¥­¥ã¥Ã¥·¥å¤·¤Ê¤¤(set authorization´Ø·¸¤Î¥Æ¥¹¥È¤¬Ä̤é¤Ê¤¤¤¿¤á)¡¥ + +-o °Ê²¼¤Î¥×¥í¥È¥³¥ë¤Î¼ÂÁõ + + - AuthenticationCleartextPassword + - AuthenticationCryptPassword + - AuthenticationMD5Password + - BinaryRow + - NotificationResponse + - PasswordPacket + - FunctionCall + - FunctionResultResponse + +-o ¥³¥ó¥Õ¥£¥°¥Õ¥¡¥¤¥ë¤¬¸«¤Ä¤«¤é¤Ê¤¤¤È¤­¤ÏÆâÉô¤Ç»ý¤Ã¤Æ¤¤¤ë¥Ç¥Õ¥©¥ë¥ÈÃͤò + »È¤¦¡¥ + +-o regression test¤òÄ̤¹ + +- o ¥×¥í¥È¥³¥ë3(PostgreSQL 7.4)¤ËÂбþ¤¹¤ë->¤È¤ê¤¢¤¨¤ºV3 request¤¬Í褿¤é + V2¤ËfallbackÍ×µá¤ò¥Õ¥í¥ó¥È¥¨¥ó¥É¤ËÁ÷¤ë¤è¤¦¤Ë²þÎɤ·¤¿¡¥V3¥×¥í¥È¥³¥ë¤Ø + ¤ÎnativeÂбþ¤Ï¤Þ¤À¡¥ + + ¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬V2->¥Ð¥Ã¥¯¥¨¥ó¥É¤ËV2¤Ç¥Í¥´ + - V2¥Ð¥Ã¥¯¥¨¥ó¥É->ÀܳÀ®¸ù + - V3¥Ð¥Ã¥¯¥¨¥ó¥É->ÀܳÀ®¸ù + + ¥Õ¥í¥ó¥È¥¨¥ó¥É¤¬V3->¥Ð¥Ã¥¯¥¨¥ó¥É¤ËV3¤Ç¥Í¥´ + - V2¥Ð¥Ã¥¯¥¨¥ó¥É->Àܳ¼ºÇÔ(¤³¤³¤Ç¹¹¤Ë¥Õ¥í¥ó¥È¥¨ + ¥ó¥É¤ËV2¤ò¥Í¥´¤·¡¤¤½¤Î¤¢¤ÈV2¤Ç¥Ð¥Ã¥¯¥¨¥ó¥É¤ËÀÜ + ³¤Ë¹Ô¤¯¤³¤È¤â¤Ç¤­¤ë)->¼ÂÁõ¤·¤¿ + - V3¥Ð¥Ã¥¯¥¨¥ó¥É->ÀܳÀ®¸ù + + ·ë¶É¡¤¥Õ¥í¥ó¥È¥¨¥ó¥É¤Îoffer¤·¤¿¥×¥í¥È¥³¥ë¥Ð¡¼¥¸¥ç¥ó¤ò³Ð¤¨¤Æ¤ª¤­¡¤¤½ + ¤ì¤ò»È¤Ã¤Æ¥Ð¥Ã¥¯¥¨¥ó¥É¤ËÀܳ¤¹¤ì¤ÐOK + +-o Unix¥É¥á¥¤¥ó¥½¥±¥Ã¥È¤Î¥Ñ¥¹¤òpgpool.conf¤ÇÊѹ¹²Äǽ¤Ë¤¹¤ë(debianÂкö) + +-o cancel request¤Ø¤ÎÂбþ diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 0000000..61972a3 --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,1077 @@ +# generated automatically by aclocal 1.9 -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. +# This file is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +# -*- Autoconf -*- +# Copyright (C) 2002, 2003 Free Software Foundation, Inc. +# Generated from amversion.in; do not edit by hand. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + +# AM_AUTOMAKE_VERSION(VERSION) +# ---------------------------- +# Automake X.Y traces this macro to ensure aclocal.m4 has been +# generated from the m4 files accompanying Automake X.Y. +AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.9"]) + +# AM_SET_CURRENT_AUTOMAKE_VERSION +# ------------------------------- +# Call AM_AUTOMAKE_VERSION so it can be traced. +# This function is AC_REQUIREd by AC_INIT_AUTOMAKE. +AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], + [AM_AUTOMAKE_VERSION([1.9])]) + +# AM_AUX_DIR_EXPAND + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets +# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to +# `$srcdir', `$srcdir/..', or `$srcdir/../..'. +# +# Of course, Automake must honor this variable whenever it calls a +# tool from the auxiliary directory. The problem is that $srcdir (and +# therefore $ac_aux_dir as well) can be either absolute or relative, +# depending on how configure is run. This is pretty annoying, since +# it makes $ac_aux_dir quite unusable in subdirectories: in the top +# source directory, any form will work fine, but in subdirectories a +# relative path needs to be adjusted first. +# +# $ac_aux_dir/missing +# fails when called from a subdirectory if $ac_aux_dir is relative +# $top_srcdir/$ac_aux_dir/missing +# fails if $ac_aux_dir is absolute, +# fails when called from a subdirectory in a VPATH build with +# a relative $ac_aux_dir +# +# The reason of the latter failure is that $top_srcdir and $ac_aux_dir +# are both prefixed by $srcdir. In an in-source build this is usually +# harmless because $srcdir is `.', but things will broke when you +# start a VPATH build or use an absolute $srcdir. +# +# So we could use something similar to $top_srcdir/$ac_aux_dir/missing, +# iff we strip the leading $srcdir from $ac_aux_dir. That would be: +# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"` +# and then we would define $MISSING as +# MISSING="\${SHELL} $am_aux_dir/missing" +# This will work as long as MISSING is not called from configure, because +# unfortunately $(top_srcdir) has no meaning in configure. +# However there are other variables, like CC, which are often used in +# configure, and could therefore not use this "fixed" $ac_aux_dir. +# +# Another solution, used here, is to always expand $ac_aux_dir to an +# absolute PATH. The drawback is that using absolute paths prevent a +# configured tree to be moved without reconfiguration. + +AC_DEFUN([AM_AUX_DIR_EXPAND], +[dnl Rely on autoconf to set up CDPATH properly. +AC_PREREQ([2.50])dnl +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` +]) + +# AM_CONDITIONAL -*- Autoconf -*- + +# Copyright (C) 1997, 2000, 2001, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 6 + +# AM_CONDITIONAL(NAME, SHELL-CONDITION) +# ------------------------------------- +# Define a conditional. +AC_DEFUN([AM_CONDITIONAL], +[AC_PREREQ(2.52)dnl + ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])], + [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl +AC_SUBST([$1_TRUE]) +AC_SUBST([$1_FALSE]) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi +AC_CONFIG_COMMANDS_PRE( +[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then + AC_MSG_ERROR([[conditional "$1" was never defined. +Usually this means the macro was only invoked conditionally.]]) +fi])]) + +# serial 7 -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + + +# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be +# written in clear, in which case automake, when reading aclocal.m4, +# will think it sees a *use*, and therefore will trigger all it's +# C support machinery. Also note that it means that autoscan, seeing +# CC etc. in the Makefile, will ask for an AC_PROG_CC use... + + + +# _AM_DEPENDENCIES(NAME) +# ---------------------- +# See how the compiler implements dependency checking. +# NAME is "CC", "CXX", "GCJ", or "OBJC". +# We try a few techniques and use that to set a single cache variable. +# +# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was +# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular +# dependency, and given that the user is not expected to run this macro, +# just rely on AC_PROG_CC. +AC_DEFUN([_AM_DEPENDENCIES], +[AC_REQUIRE([AM_SET_DEPDIR])dnl +AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl +AC_REQUIRE([AM_MAKE_INCLUDE])dnl +AC_REQUIRE([AM_DEP_TRACK])dnl + +ifelse([$1], CC, [depcc="$CC" am_compiler_list=], + [$1], CXX, [depcc="$CXX" am_compiler_list=], + [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'], + [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'], + [depcc="$$1" am_compiler_list=]) + +AC_CACHE_CHECK([dependency style of $depcc], + [am_cv_$1_dependencies_compiler_type], +[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_$1_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_$1_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_$1_dependencies_compiler_type=none +fi +]) +AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type]) +AM_CONDITIONAL([am__fastdep$1], [ + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_$1_dependencies_compiler_type" = gcc3]) +]) + + +# AM_SET_DEPDIR +# ------------- +# Choose a directory name for dependency files. +# This macro is AC_REQUIREd in _AM_DEPENDENCIES +AC_DEFUN([AM_SET_DEPDIR], +[AC_REQUIRE([AM_SET_LEADING_DOT])dnl +AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl +]) + + +# AM_DEP_TRACK +# ------------ +AC_DEFUN([AM_DEP_TRACK], +[AC_ARG_ENABLE(dependency-tracking, +[ --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors]) +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi +AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno]) +AC_SUBST([AMDEPBACKSLASH]) +]) + +# Generate code to set up dependency tracking. -*- Autoconf -*- + +# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +#serial 2 + +# _AM_OUTPUT_DEPENDENCY_COMMANDS +# ------------------------------ +AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], +[for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`AS_DIRNAME("$mf")` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`AS_DIRNAME(["$file"])` + AS_MKDIR_P([$dirpart/$fdir]) + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done +])# _AM_OUTPUT_DEPENDENCY_COMMANDS + + +# AM_OUTPUT_DEPENDENCY_COMMANDS +# ----------------------------- +# This macro should only be invoked once -- use via AC_REQUIRE. +# +# This code is only required when automatic dependency tracking +# is enabled. FIXME. This creates each `.P' file that we will +# need in order to bootstrap the dependency handling code. +AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], +[AC_CONFIG_COMMANDS([depfiles], + [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], + [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) +]) + +# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*- + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 7 + +# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS. +AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)]) + +# Do all the work for Automake. -*- Autoconf -*- + +# This macro actually does too much some checks are only needed if +# your package does certain things. But this isn't really a big deal. + +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 11 + +# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE]) +# AM_INIT_AUTOMAKE([OPTIONS]) +# ----------------------------------------------- +# The call with PACKAGE and VERSION arguments is the old style +# call (pre autoconf-2.50), which is being phased out. PACKAGE +# and VERSION should now be passed to AC_INIT and removed from +# the call to AM_INIT_AUTOMAKE. +# We support both call styles for the transition. After +# the next Automake release, Autoconf can make the AC_INIT +# arguments mandatory, and then we can depend on a new Autoconf +# release and drop the old call support. +AC_DEFUN([AM_INIT_AUTOMAKE], +[AC_PREREQ([2.58])dnl +dnl Autoconf wants to disallow AM_ names. We explicitly allow +dnl the ones we care about. +m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl +AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl +AC_REQUIRE([AC_PROG_INSTALL])dnl +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi +AC_SUBST([CYGPATH_W]) + +# Define the identity of the package. +dnl Distinguish between old-style and new-style calls. +m4_ifval([$2], +[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl + AC_SUBST([PACKAGE], [$1])dnl + AC_SUBST([VERSION], [$2])], +[_AM_SET_OPTIONS([$1])dnl + AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl + AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl + +_AM_IF_OPTION([no-define],, +[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) + AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl + +# Some tools Automake needs. +AC_REQUIRE([AM_SANITY_CHECK])dnl +AC_REQUIRE([AC_ARG_PROGRAM])dnl +AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version}) +AM_MISSING_PROG(AUTOCONF, autoconf) +AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version}) +AM_MISSING_PROG(AUTOHEADER, autoheader) +AM_MISSING_PROG(MAKEINFO, makeinfo) +AM_PROG_INSTALL_SH +AM_PROG_INSTALL_STRIP +AC_REQUIRE([AM_PROG_MKDIR_P])dnl +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +AC_REQUIRE([AC_PROG_AWK])dnl +AC_REQUIRE([AC_PROG_MAKE_SET])dnl +AC_REQUIRE([AM_SET_LEADING_DOT])dnl +_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])], + [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])], + [_AM_PROG_TAR([v7])])]) +_AM_IF_OPTION([no-dependencies],, +[AC_PROVIDE_IFELSE([AC_PROG_CC], + [_AM_DEPENDENCIES(CC)], + [define([AC_PROG_CC], + defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl +AC_PROVIDE_IFELSE([AC_PROG_CXX], + [_AM_DEPENDENCIES(CXX)], + [define([AC_PROG_CXX], + defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl +]) +]) + + +# When config.status generates a header, we must update the stamp-h file. +# This file resides in the same directory as the config header +# that is generated. The stamp files are numbered to have different names. + +# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the +# loop where config.status creates the headers, so we can generate +# our stamp files there. +AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK], +[# Compute $1's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $1 | $1:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count]) + +# AM_PROG_INSTALL_SH +# ------------------ +# Define $install_sh. + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +AC_DEFUN([AM_PROG_INSTALL_SH], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +install_sh=${install_sh-"$am_aux_dir/install-sh"} +AC_SUBST(install_sh)]) + +# -*- Autoconf -*- +# Copyright (C) 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + +# Check whether the underlying file-system supports filenames +# with a leading dot. For instance MS-DOS doesn't. +AC_DEFUN([AM_SET_LEADING_DOT], +[rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null +AC_SUBST([am__leading_dot])]) + + +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 +# Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 4 + +# AM_PROG_LEX +# ----------- +# Autoconf leaves LEX=: if lex or flex can't be found. Change that to a +# "missing" invocation, for better error output. +AC_DEFUN([AM_PROG_LEX], +[AC_PREREQ(2.50)dnl +AC_REQUIRE([AM_MISSING_HAS_RUN])dnl +AC_REQUIRE([AC_PROG_LEX])dnl +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi]) + +# Check to see how 'make' treats includes. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# AM_MAKE_INCLUDE() +# ----------------- +# Check to see how make treats includes. +AC_DEFUN([AM_MAKE_INCLUDE], +[am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +AC_MSG_CHECKING([for style of include used by $am_make]) +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi +AC_SUBST([am__include]) +AC_SUBST([am__quote]) +AC_MSG_RESULT([$_am_result]) +rm -f confinc confmf +]) + +# -*- Autoconf -*- + + +# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_MISSING_PROG(NAME, PROGRAM) +# ------------------------------ +AC_DEFUN([AM_MISSING_PROG], +[AC_REQUIRE([AM_MISSING_HAS_RUN]) +$1=${$1-"${am_missing_run}$2"} +AC_SUBST($1)]) + + +# AM_MISSING_HAS_RUN +# ------------------ +# Define MISSING if not defined so far and test if it supports --run. +# If it does, set am_missing_run to use it, otherwise, to nothing. +AC_DEFUN([AM_MISSING_HAS_RUN], +[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + AC_MSG_WARN([`missing' script is too old or missing]) +fi +]) + +# AM_PROG_MKDIR_P +# --------------- +# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise. + +# Copyright (C) 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories +# created by `make install' are always world readable, even if the +# installer happens to have an overly restrictive umask (e.g. 077). +# This was a mistake. There are at least two reasons why we must not +# use `-m 0755': +# - it causes special bits like SGID to be ignored, +# - it may be too restrictive (some setups expect 775 directories). +# +# Do not use -m 0755 and let people choose whatever they expect by +# setting umask. +# +# We cannot accept any implementation of `mkdir' that recognizes `-p'. +# Some implementations (such as Solaris 8's) are not thread-safe: if a +# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c' +# concurrently, both version can detect that a/ is missing, but only +# one can create it and the other will error out. Consequently we +# restrict ourselves to GNU make (using the --version option ensures +# this.) +AC_DEFUN([AM_PROG_MKDIR_P], +[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi +AC_SUBST([mkdir_p])]) + +# Helper functions for option handling. -*- Autoconf -*- + +# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 2 + +# _AM_MANGLE_OPTION(NAME) +# ----------------------- +AC_DEFUN([_AM_MANGLE_OPTION], +[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])]) + +# _AM_SET_OPTION(NAME) +# ------------------------------ +# Set option NAME. Presently that only means defining a flag for this option. +AC_DEFUN([_AM_SET_OPTION], +[m4_define(_AM_MANGLE_OPTION([$1]), 1)]) + +# _AM_SET_OPTIONS(OPTIONS) +# ---------------------------------- +# OPTIONS is a space-separated list of Automake options. +AC_DEFUN([_AM_SET_OPTIONS], +[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])]) + +# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET]) +# ------------------------------------------- +# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise. +AC_DEFUN([_AM_IF_OPTION], +[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) + +# +# Check to make sure that the build environment is sane. +# + +# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 3 + +# AM_SANITY_CHECK +# --------------- +AC_DEFUN([AM_SANITY_CHECK], +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$[*]" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$[*]" != "X $srcdir/configure conftest.file" \ + && test "$[*]" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "$[2]" = conftest.file + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +AC_MSG_RESULT(yes)]) + +# AM_PROG_INSTALL_STRIP + +# Copyright (C) 2001, 2003 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# One issue with vendor `install' (even GNU) is that you can't +# specify the program used to strip binaries. This is especially +# annoying in cross-compiling environments, where the build's strip +# is unlikely to handle the host's binaries. +# Fortunately install-sh will honor a STRIPPROG variable, so we +# always use install-sh in `make install-strip', and initialize +# STRIPPROG with the value of the STRIP variable (set by the user). +AC_DEFUN([AM_PROG_INSTALL_STRIP], +[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +dnl Don't test for $cross_compiling = yes, because it might be `maybe'. +if test "$cross_compiling" != no; then + AC_CHECK_TOOL([STRIP], [strip], :) +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" +AC_SUBST([INSTALL_STRIP_PROGRAM])]) + +# Check how to create a tarball. -*- Autoconf -*- + +# Copyright (C) 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# serial 1 + + +# _AM_PROG_TAR(FORMAT) +# -------------------- +# Check how to create a tarball in format FORMAT. +# FORMAT should be one of `v7', `ustar', or `pax'. +# +# Substitute a variable $(am__tar) that is a command +# writing to stdout a FORMAT-tarball containing the directory +# $tardir. +# tardir=directory && $(am__tar) > result.tar +# +# Substitute a variable $(am__untar) that extract such +# a tarball read from stdin. +# $(am__untar) < result.tar +AC_DEFUN([_AM_PROG_TAR], +[# Always define AMTAR for backward compatibility. +AM_MISSING_PROG([AMTAR], [tar]) +m4_if([$1], [v7], + [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'], + [m4_case([$1], [ustar],, [pax],, + [m4_fatal([Unknown tar format])]) +AC_MSG_CHECKING([how to create a $1 tar archive]) +# Loop over all known methods to create a tar archive until one works. +_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none' +_am_tools=${am_cv_prog_tar_$1-$_am_tools} +# Do not fold the above two line into one, because Tru64 sh and +# Solaris sh will not grok spaces in the rhs of `-'. +for _am_tool in $_am_tools +do + case $_am_tool in + gnutar) + for _am_tar in tar gnutar gtar; + do + AM_RUN_LOG([$_am_tar --version]) && break + done + am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"' + am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"' + am__untar="$_am_tar -xf -" + ;; + plaintar) + # Must skip GNU tar: if it does not support --format= it doesn't create + # ustar tarball either. + (tar --version) >/dev/null 2>&1 && continue + am__tar='tar chf - "$$tardir"' + am__tar_='tar chf - "$tardir"' + am__untar='tar xf -' + ;; + pax) + am__tar='pax -L -x $1 -w "$$tardir"' + am__tar_='pax -L -x $1 -w "$tardir"' + am__untar='pax -r' + ;; + cpio) + am__tar='find "$$tardir" -print | cpio -o -H $1 -L' + am__tar_='find "$tardir" -print | cpio -o -H $1 -L' + am__untar='cpio -i -H $1 -d' + ;; + none) + am__tar=false + am__tar_=false + am__untar=false + ;; + esac + + # If the value was cached, stop now. We just wanted to have am__tar + # and am__untar set. + test -n "${am_cv_prog_tar_$1}" && break + + # tar/untar a dummy directory, and stop if the command works + rm -rf conftest.dir + mkdir conftest.dir + echo GrepMe > conftest.dir/file + AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar]) + rm -rf conftest.dir + if test -s conftest.tar; then + AM_RUN_LOG([$am__untar /dev/null 2>&1 && break + fi +done +rm -rf conftest.dir + +AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool]) +AC_MSG_RESULT([$am_cv_prog_tar_$1])]) +AC_SUBST([am__tar]) +AC_SUBST([am__untar]) +]) # _AM_PROG_TAR + diff --git a/child.c b/child.c new file mode 100644 index 0000000..c48d88a --- /dev/null +++ b/child.c @@ -0,0 +1,1006 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * child.c: child process main + * + */ +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_NETINET_TCP_H +#include +#endif + +#include + +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_FCNTL_H +#include +#endif + +#include "pool.h" + +#ifdef NONE_BLOCK +static void set_nonblock(int fd); +#endif +#ifdef NOT_USED +static void unset_nonblock(int fd); +#endif + +static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *timeout); +static StartupPacket *read_startup_packet(POOL_CONNECTION *cp); +static int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp); +static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend); +static void cancel_request(CancelPacket *sp, int secondary_backend); +static RETSIGTYPE die(int sig); +static int send_params(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static void send_frontend_exits(void); + +/* + * non 0 means SIGTERM(smart shutdown) or SIGINT(fast shutdown) has arrived + */ +static int exit_request; + +static int idle; /* non 0 means this child is in idle state */ + +/* +* child main loop +*/ +void do_child(int unix_fd, int inet_fd) +{ + POOL_CONNECTION *frontend; + POOL_CONNECTION_POOL *backend; + struct timeval now; + struct timezone tz; + int child_idle_sec; + struct timeval timeout; + static int connected; + + pool_debug("I am %d", getpid()); + + /* set up signal handlers */ + signal(SIGALRM, SIG_DFL); + signal(SIGTERM, die); + signal(SIGINT, die); + signal(SIGQUIT, die); + signal(SIGCHLD, SIG_DFL); + signal(SIGUSR1, SIG_DFL); + signal(SIGUSR2, SIG_DFL); + signal(SIGPIPE, SIG_IGN); + +#ifdef NONE_BLOCK + /* set listen fds to none block */ + set_nonblock(unix_fd); + if (inet_fd) + { + set_nonblock(inet_fd); + } +#endif + + /* initialize random seed */ + gettimeofday(&now, &tz); + srandom((unsigned int) now.tv_usec); + + /* initialize connection pool */ + if (pool_init_cp()) + { + exit(1); + } + + child_idle_sec = 0; + + timeout.tv_sec = pool_config.child_life_time; + timeout.tv_usec = 0; + + for (;;) + { + int connection_reuse = 1; + int ssl_request = 0; + StartupPacket *sp; + + /* pgpool stop request already sent? */ + if (exit_request) + { + die(0); + exit(0); + } + + idle = 1; + + /* perform accept() */ + frontend = do_accept(unix_fd, inet_fd, &timeout); + + if (frontend == NULL) + { + /* check select() timeout */ + if (connected && pool_config.child_life_time > 0 && + timeout.tv_sec == 0 && timeout.tv_usec == 0) + { + pool_debug("child life %d seconds expired", pool_config.child_life_time); + send_frontend_exits(); + exit(2); + } + continue; + } + +#ifdef NOT_USED + /* set frontend fd to blocking */ + unset_nonblock(frontend->fd); +#endif + + /* set busy flag and clear child idle timer */ + idle = 0; + child_idle_sec = 0; + + /* disable timeout */ + pool_disable_timeout(); + + /* read the startup packet */ + retry_startup: + sp = read_startup_packet(frontend); + if (sp == NULL) + { + /* failed to read the startup packet. return to the accept() loop */ + pool_close(frontend); + continue; + } + + /* cancel request? */ + if (sp->major == 1234 && sp->minor == 5678) + { + cancel_request((CancelPacket *)sp->startup_packet, 0); + if (DUAL_MODE) + cancel_request((CancelPacket *)sp->startup_packet, 1); + pool_close(frontend); + pool_free_startup_packet(sp); + continue; + } + + /* SSL? */ + if (sp->major == 1234 && sp->minor == 5679) + { + /* SSL not supported */ + pool_debug("SSLRequest: sent N; retry startup"); + if (ssl_request) + { + pool_close(frontend); + pool_free_startup_packet(sp); + continue; + } + + /* + * say to the frontend "we do not suppport SSL" + * note that this is not a NOTICE response despite it's an 'N'! + */ + pool_write_and_flush(frontend, "N", 1); + ssl_request = 1; + pool_free_startup_packet(sp); + goto retry_startup; + } + + /* + * Ok, negotiaton with frontend has been done. Let's go to the next step. + */ + + /* + * if there's no connection associated with user and database, + * we need to connect to the backend and send the startup packet. + */ + + /* look for existing connection */ + if ((backend = pool_get_cp(sp->user, sp->database, sp->major)) == NULL) + { + /* create a new connection to backend */ + connection_reuse = 0; + + if ((backend = connect_backend(sp, frontend)) == NULL) + continue; + } + else + { + /* we don't need Startup Packet info anymore */ + pool_free_startup_packet(sp); + + /* reuse existing connection to backend */ + + if (pool_do_reauth(frontend, backend)) + { + pool_close(frontend); + continue; + } + + if (MAJOR(backend) == 3) + { + if (send_params(frontend, backend)) + { + pool_close(frontend); + continue; + } + } + + /* send ReadyForQuery to frontend */ + pool_write(frontend, "Z", 1); + + if (MAJOR(backend) == 3) + { + int len; + char tstate; + + len = htonl(5); + pool_write(frontend, &len, sizeof(len)); + tstate = TSTATE(backend); + pool_write(frontend, &tstate, 1); + } + + if (pool_flush(frontend) < 0) + { + pool_close(frontend); + continue; + } + + } + + /* enable query result read timeout if non strict mode */ + if (pool_config.replication_strict == 0) + pool_enable_timeout(); + + connected = 1; + + /* query process loop */ + for (;;) + { + POOL_STATUS status; + + status = pool_process_query(frontend, backend, 0); + + sp = MASTER_CONNECTION(backend)->sp; + + switch (status) + { + /* client exits */ + case POOL_END: + /* + * do not cache connection if: + * pool_config.connection_cahe == 0 or + * datase name is template0, template1, or regression + */ + if (pool_config.connection_cache == 0 || + !strcmp(sp->database, "template0") || + !strcmp(sp->database, "template1") || + !strcmp(sp->database, "regression")) + { + pool_close(frontend); + pool_send_frontend_exits(backend); + pool_discard_cp(sp->user, sp->database, sp->major); + } + else + { + POOL_STATUS status1; + + /* send reset request to backend */ + status1 = pool_process_query(frontend, backend, 1); + pool_close(frontend); + + /* if we detect errors on resetting connection, we need to discard + * this connection since it might be in unknown status + */ + if (status1 != POOL_CONTINUE) + pool_discard_cp(sp->user, sp->database, sp->major); + else + pool_connection_pool_timer(backend); + } + break; + + /* error occured. discard backend connection pool + and disconnect connection to the frontend */ + case POOL_ERROR: +#ifdef NOT_USED + pool_discard_cp(sp->user, sp->database); + pool_close(frontend); + notice_backend_error(); +#endif + pool_log("do_child: exits with status 1 due to error"); + exit(1); + break; + + /* fatal error occured. just exit myself... */ + case POOL_FATAL: + notice_backend_error(1); + exit(1); + break; + + /* not implemented yet */ + case POOL_IDLE: + do_accept(unix_fd, inet_fd, &timeout); + pool_debug("accept while idle"); + break; + + default: + break; + } + + if (status != POOL_CONTINUE) + break; + } + + timeout.tv_sec = pool_config.child_life_time; + timeout.tv_usec = 0; + + } + exit(0); +} + +/* ------------------------------------------------------------------- + * private functions + * ------------------------------------------------------------------- + */ + +#ifdef NONE_BLOCK +/* + * set non-block flag + */ +static void set_nonblock(int fd) +{ + int var; + + /* set fd to none blocking */ + var = fcntl(fd, F_GETFL, 0); + if (var == -1) + { + pool_error("fcntl failed. %s", strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFL, var | O_NONBLOCK) == -1) + { + pool_error("fcntl failed. %s", strerror(errno)); + exit(1); + } +} +#endif + +#ifdef NOT_USED +/* + * unset non-block flag + */ +static void unset_nonblock(int fd) +{ + int var; + + /* set fd to none blocking */ + var = fcntl(fd, F_GETFL, 0); + if (var == -1) + { + pool_error("fcntl failed. %s", strerror(errno)); + exit(1); + } + if (fcntl(fd, F_SETFL, var & ~O_NONBLOCK) == -1) + { + pool_error("fcntl failed. %s", strerror(errno)); + exit(1); + } +} +#endif + +/* +* perform accept() and return new fd +*/ +static POOL_CONNECTION *do_accept(int unix_fd, int inet_fd, struct timeval *timeout) +{ + fd_set readmask; + int fds; + + struct sockaddr addr; + socklen_t addrlen; + int fd = 0; + int afd; + int inet = 0; + POOL_CONNECTION *cp; +#ifdef ACCEPT_PERFORMANCE + struct timeval now1, now2; + static long atime; + static int cnt; +#endif + struct timeval *timeoutval; + struct timeval tv1, tv2, tmback; + + FD_ZERO(&readmask); + FD_SET(unix_fd, &readmask); + if (inet_fd) + FD_SET(inet_fd, &readmask); + + if (timeout->tv_sec == 0 && timeout->tv_usec == 0) + timeoutval = NULL; + else + { + timeoutval = timeout; + tmback.tv_sec = timeout->tv_sec; + tmback.tv_usec = timeout->tv_usec; + gettimeofday(&tv1, NULL); + +#ifdef DEBUG + pool_log("before select = {%d, %d}", timeoutval->tv_sec, timeoutval->tv_usec); + pool_log("g:before select = {%d, %d}", tv1.tv_sec, tv1.tv_usec); +#endif + } + + fds = select(Max(unix_fd, inet_fd)+1, &readmask, NULL, NULL, timeoutval); + + /* + * following code fragment computes remaining timeout val in a + * portable way. Linux does this automazically but other platforms do not. + */ + if (timeoutval) + { + gettimeofday(&tv2, NULL); + + tmback.tv_usec -= tv2.tv_usec - tv1.tv_usec; + tmback.tv_sec -= tv2.tv_sec - tv1.tv_sec; + + if (tmback.tv_usec < 0) + { + tmback.tv_sec--; + if (tmback.tv_sec < 0) + { + timeout->tv_sec = 0; + timeout->tv_usec = 0; + } + else + { + tmback.tv_usec += 1000000; + timeout->tv_sec = tmback.tv_sec; + timeout->tv_usec = tmback.tv_usec; + } + } +#ifdef DEBUG + pool_log("g:after select = {%d, %d}", tv2.tv_sec, tv2.tv_usec); + pool_log("after select = {%d, %d}", timeout->tv_sec, timeout->tv_usec); +#endif + } + + if (fds == -1) + { + if (errno == EAGAIN || errno == EINTR) + return NULL; + + pool_error("select() failed. reason %s", strerror(errno)); + return NULL; + } + + /* timeout */ + if (fds == 0) + { + return NULL; + } + + if (FD_ISSET(unix_fd, &readmask)) + { + fd = unix_fd; + } + + if (FD_ISSET(inet_fd, &readmask)) + { + fd = inet_fd; + inet++; + } + + /* + * Note that some SysV systems do not work here. For those + * systems, we need some locking mechanism for the fd. + */ + addrlen = sizeof(addr); + +#ifdef ACCEPT_PERFORMANCE + gettimeofday(&now1,0); +#endif + afd = accept(fd, &addr, &addrlen); + if (afd < 0) + { + /* + * "Resource temporarily unavailable" (EAGAIN or EWOULDBLOCK) + * can be silently ignored. + */ + if (errno != EAGAIN && errno != EWOULDBLOCK) + pool_error("accept() failed. reason: %s", strerror(errno)); + return NULL; + } +#ifdef ACCEPT_PERFORMANCE + gettimeofday(&now2,0); + atime += (now2.tv_sec - now1.tv_sec)*1000000 + (now2.tv_usec - now1.tv_usec); + cnt++; + if (cnt % 100 == 0) + { + pool_log("cnt: %d atime: %ld", cnt, atime); + } +#endif + pool_debug("I am %d accept fd %d", getpid(), afd); + + /* set NODELAY and KEEPALIVE options if INET connection */ + if (inet) + { + int on = 1; + + if (setsockopt(afd, IPPROTO_TCP, TCP_NODELAY, + (char *) &on, + sizeof(on)) < 0) + { + pool_error("do_accept: setsockopt() failed: %s", strerror(errno)); + close(afd); + return NULL; + } + if (setsockopt(afd, SOL_SOCKET, SO_KEEPALIVE, + (char *) &on, + sizeof(on)) < 0) + { + pool_error("do_accept: setsockopt() failed: %s", strerror(errno)); + close(afd); + return NULL; + } + } + + if ((cp = pool_open(afd)) == NULL) + { + close(afd); + return NULL; + } + return cp; +} + +/* +* read startup packet +*/ +static StartupPacket *read_startup_packet(POOL_CONNECTION *cp) +{ + StartupPacket *sp; + StartupPacket_v2 *sp2; + int protov; + int len; + char *p; + + sp = (StartupPacket *)calloc(sizeof(*sp), 1); + if (!sp) + { + pool_error("read_startup_packet: out of memory"); + return NULL; + } + + /* read startup packet length */ + if (pool_read(cp, &len, sizeof(len))) + { + return NULL; + } + len = ntohl(len); + len -= sizeof(len); + + if (len <= 0) + { + pool_error("read_startup_packet: incorrect packet length (%d)", len); + } + + sp->startup_packet = calloc(len, 1); + if (!sp->startup_packet) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + + /* read startup packet */ + if (pool_read(cp, sp->startup_packet, len)) + { + pool_free_startup_packet(sp); + return NULL; + } + + sp->len = len; + memcpy(&protov, sp->startup_packet, sizeof(protov)); + sp->major = ntohl(protov)>>16; + sp->minor = ntohl(protov) & 0x0000ffff; + p = sp->startup_packet; + + switch(sp->major) + { + case PROTO_MAJOR_V2: /* V2 */ + sp2 = (StartupPacket_v2 *)(sp->startup_packet); + + sp->database = calloc(SM_DATABASE+1, 1); + if (!sp->database) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + strncpy(sp->database, sp2->database, SM_DATABASE); + + sp->user = calloc(SM_USER+1, 1); + if (!sp->user) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + strncpy(sp->user, sp2->user, SM_USER); + + break; + + case PROTO_MAJOR_V3: /* V3 */ + p += sizeof(int); /* skip protocol version info */ + + while(*p) + { + if (!strcmp("user", p)) + { + p += (strlen(p) + 1); + sp->user = strdup(p); + if (!sp->user) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + } + else if (!strcmp("database", p)) + { + p += (strlen(p) + 1); + sp->database = strdup(p); + if (!sp->database) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + } + p += (strlen(p) + 1); + } + break; + + case 1234: /* cancel or SSL request */ + /* set dummy database, user info */ + sp->database = calloc(1, 1); + if (!sp->database) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + sp->user = calloc(1, 1); + if (!sp->user) + { + pool_error("read_startup_packet: out of memory"); + pool_free_startup_packet(sp); + return NULL; + } + break; + + default: + pool_error("read_startup_packet: invalid major no: %d", sp->major); + pool_free_startup_packet(sp); + return NULL; + } + + pool_debug("Protocol Major: %d Minor: %d database: %s user: %s", + sp->major, sp->minor, sp->database, sp->user); + + return sp; +} + +/* +* send startup packet +*/ +static int send_startup_packet(POOL_CONNECTION_POOL_SLOT *cp) +{ + int len; + + len = htonl(cp->sp->len + sizeof(len)); + pool_write(cp->con, &len, sizeof(len)); + return pool_write_and_flush(cp->con, cp->sp->startup_packet, cp->sp->len); +} + +/* + * process cancel request + */ +static void cancel_request(CancelPacket *sp, int secondary_backend) +{ + int len; + int fd; + POOL_CONNECTION *con; + + pool_debug("Cancel request received"); + + if (secondary_backend) + { + if (*pool_config.secondary_backend_host_name == '\0') + fd = connect_unix_domain_socket(1); + else + fd = connect_inet_domain_socket(1); + } + else + { + if (*pool_config.current_backend_host_name == '\0') + fd = connect_unix_domain_socket(0); + else + fd = connect_inet_domain_socket(0); + } + + if (fd < 0) + { + pool_error("Could not create socket for sending cancel request"); + return; + } + + con = pool_open(fd); + if (con == NULL) + return; + + len = htonl(sizeof(len) + sizeof(CancelPacket)); + pool_write(con, &len, sizeof(len)); + + if (pool_write_and_flush(con, sp, sizeof(CancelPacket)) < 0) + pool_error("Could not send cancel request packet"); + pool_close(con); +} + +static POOL_CONNECTION_POOL *connect_backend(StartupPacket *sp, POOL_CONNECTION *frontend) +{ + POOL_CONNECTION_POOL *backend; + + /* connect to the backend */ + backend = pool_create_cp(); + if (backend == NULL) + { + pool_send_error_message(frontend, sp->major, "XX000", "connection cache is full", "", + "increace max_pool", __FILE__, __LINE__); + pool_close(frontend); + pool_free_startup_packet(sp); + return NULL; + } + + /* mark this is a backend connection */ + backend->slots[0]->con->isbackend = 1; + + /* + * save startup packet info + */ + backend->slots[0]->sp = sp; + + if (DUAL_MODE) + { + backend->slots[1]->con->isbackend = 1; + backend->slots[1]->con->issecondary_backend = 1; + /* + * save startup packet info + */ + backend->slots[1]->sp = sp; + } + + /* send startup packet */ + if (send_startup_packet(backend->slots[0]) < 0) + { + pool_error("do_child: fails to send startup packet to the backend"); + pool_discard_cp(sp->user, sp->database, sp->major); + pool_close(frontend); + return NULL; + } + + /* send startup packet */ + if (DUAL_MODE) + { + if (send_startup_packet(backend->slots[1]) < 0) + { + pool_error("do_child: fails to send startup packet to the secondary backend"); + pool_discard_cp(sp->user, sp->database, sp->major); + pool_close(frontend); + return NULL; + } + } + + /* + * do authentication stuff + */ + if (pool_do_auth(frontend, backend)) + { + pool_close(frontend); + pool_discard_cp(sp->user, sp->database, sp->major); + return NULL; + } + return backend; +} + +static RETSIGTYPE die(int sig) +{ + exit_request = 1; + + switch (sig) + { + case SIGTERM: /* smart shutdown */ + if (idle == 0) + return; + + case SIGINT: /* fast shutdown */ + case SIGQUIT: /* immediate shutdown */ + exit(0); + break; + default: + break; + } + + send_frontend_exits(); + + exit(0); +} + +static void send_frontend_exits(void) +{ + int i; + POOL_CONNECTION_POOL *p = pool_connection_pool; + + for (i=0;isp->user == NULL) + continue; + pool_send_frontend_exits(p); + } +} + +static int send_params(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +{ + int index; + char *name, *value; + int len, sendlen; + + index = 0; + while (pool_get_param(&MASTER(backend)->params, index++, &name, &value) == 0) + { + pool_write(frontend, "S", 1); + len = sizeof(sendlen) + strlen(name) + 1 + strlen(value) + 1; + sendlen = htonl(len); + pool_write(frontend, &sendlen, sizeof(sendlen)); + pool_write(frontend, name, strlen(name) + 1); + pool_write(frontend, value, strlen(value) + 1); + } + + if (pool_flush(frontend)) + { + pool_error("pool_send_params: pool_flush() failed"); + return -1; + } + return 0; +} + +void pool_free_startup_packet(StartupPacket *sp) +{ + if (sp) + { + if (sp->startup_packet) + free(sp->startup_packet); + if (sp->database) + free(sp->database); + if (sp->user) + free(sp->user); + free(sp); + } +} + +/* + * check if we can connect to the backend + * returns 0 for ok. -1 for master down, -2 for secondary down. + */ +int health_check(void) +{ + int fd; + + /* V2 startup packet */ + typedef struct { + int len; /* startup packet length */ + StartupPacket_v2 sp; + } MySp; + MySp mysp; + char kind; + + memset(&mysp, 0, sizeof(mysp)); + mysp.len = htonl(296); + mysp.sp.protoVersion = htonl(PROTO_MAJOR_V2 << 16); + strcpy(mysp.sp.database, "template1"); + strcpy(mysp.sp.user, pool_config.health_check_user); + *mysp.sp.options = '\0'; + *mysp.sp.unused = '\0'; + *mysp.sp.tty = '\0'; + + if (*pool_config.current_backend_host_name == '\0') + fd = connect_unix_domain_socket(0); + else + fd = connect_inet_domain_socket(0); + + if (fd < 0) + { + pool_error("health check failed. master %s at port %d is down", + pool_config.current_backend_host_name, + pool_config.current_backend_port); + return -1; + } + + if (write(fd, &mysp, sizeof(mysp)) < 0) + { + pool_error("health check failed during write. master %s at port %d is down", + pool_config.current_backend_host_name, + pool_config.current_backend_port); + return -1; + } + + read(fd, &kind, 1); + + if (write(fd, "X", 1) < 0) + { + pool_error("health check failed during write. master %s at port %d is down", + pool_config.current_backend_host_name, + pool_config.current_backend_port); + return -1; + } + + close(fd); + + if (!DUAL_MODE) + return 0; + + if (*pool_config.secondary_backend_host_name == '\0') + fd = connect_unix_domain_socket(1); + else + fd = connect_inet_domain_socket(1); + + if (fd < 0) + { + pool_error("health check failed. secondary %s at port %d is down", + pool_config.secondary_backend_host_name, + pool_config.secondary_backend_port); + return -2; + } + + if (write(fd, &mysp, sizeof(mysp)) < 0) + { + pool_error("health check failed during write. master %s at port %d is down", + pool_config.current_backend_host_name, + pool_config.current_backend_port); + return -1; + } + + read(fd, &kind, 1); + + if (write(fd, "X", 1) < 0) + { + pool_error("health check failed during write. master %s at port %d is down", + pool_config.current_backend_host_name, + pool_config.current_backend_port); + return -1; + } + + close(fd); + + return 0; +} diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..60f604b --- /dev/null +++ b/config.h.in @@ -0,0 +1,153 @@ +/* config.h.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the `asprintf' function. */ +#undef HAVE_ASPRINTF + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#undef HAVE_DOPRNT + +/* Define to 1 if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the `BSD' library (-lBSD). */ +#undef HAVE_LIBBSD + +/* Define to 1 if you have the `compat' library (-lcompat). */ +#undef HAVE_LIBCOMPAT + +/* Define to 1 if you have the `gen' library (-lgen). */ +#undef HAVE_LIBGEN + +/* Define to 1 if you have the `IPC' library (-lIPC). */ +#undef HAVE_LIBIPC + +/* Define to 1 if you have the `lc' library (-llc). */ +#undef HAVE_LIBLC + +/* Define to 1 if you have the `m' library (-lm). */ +#undef HAVE_LIBM + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#undef HAVE_LIBNSL + +/* Define to 1 if you have the `PW' library (-lPW). */ +#undef HAVE_LIBPW + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#undef HAVE_LIBRESOLV + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#undef HAVE_LIBSOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_MEMORY_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_NETINET_TCP_H + +/* Define to 1 if you have the `select' function. */ +#undef HAVE_SELECT + +/* Define to 1 if you have the `setsid' function. */ +#undef HAVE_SETSID + +/* Define to 1 if you have the `sigprocmask' function. */ +#undef HAVE_SIGPROCMASK + +/* Define to 1 if you have the `socket' function. */ +#undef HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the `strdup' function. */ +#undef HAVE_STRDUP + +/* Define to 1 if you have the `strerror' function. */ +#undef HAVE_STRERROR + +/* Define to 1 if you have the `strftime' function. */ +#undef HAVE_STRFTIME + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_UNISTD_H + +/* Define to 1 if you have the `vprintf' function. */ +#undef HAVE_VPRINTF + +/* Define to 1 if you have the `wait3' system call. Deprecated, you should no + longer depend upon `wait3'. */ +#undef HAVE_WAIT3 + +/* Name of package */ +#undef PACKAGE + +/* Define to the address where bug reports for this package should be sent. */ +#undef PACKAGE_BUGREPORT + +/* Define to the full name of this package. */ +#undef PACKAGE_NAME + +/* Define to the full name and version of this package. */ +#undef PACKAGE_STRING + +/* Define to the one symbol short name of this package. */ +#undef PACKAGE_TARNAME + +/* Define to the version of this package. */ +#undef PACKAGE_VERSION + +/* Define as the return type of signal handlers (`int' or `void'). */ +#undef RETSIGTYPE + +/* Define to 1 if you have the ANSI C header files. */ +#undef STDC_HEADERS + +/* Define to 1 if you can safely include both and . */ +#undef TIME_WITH_SYS_TIME + +/* Version number of package */ +#undef VERSION + +/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a + `char[]'. */ +#undef YYTEXT_POINTER + +/* Define to empty if `const' does not conform to ANSI C. */ +#undef const + +/* Define to `int' if does not define. */ +#undef pid_t diff --git a/configure b/configure new file mode 100755 index 0000000..1f6d7ed --- /dev/null +++ b/configure @@ -0,0 +1,6713 @@ +#! /bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.59. +# +# Copyright (C) 2003 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2 + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +exec 6>&1 + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_config_libobj_dir=. +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Maximum number of lines to put in a shell here document. +# This variable seems obsolete. It should probably be removed, and +# only ac_max_sed_lines should be used. +: ${ac_max_here_lines=38} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +# Factoring default headers for most tests. +ac_includes_default="\ +#include +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#endif" + +ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE LEX LEXLIB LEX_OUTPUT_ROOT CPP EGREP PGSQL_INCLUDE_DIR LIBOBJS LTLIBOBJS' +ac_subst_files='' + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +ac_prev= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'` + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_option in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + eval "enable_$ac_feature=no" ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "enable_$ac_feature='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package| sed 's/-/_/g'` + case $ac_option in + *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;; + *) ac_optarg=yes ;; + esac + eval "with_$ac_package='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/-/_/g'` + eval "with_$ac_package=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` + eval "$ac_envvar='$ac_optarg'" + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute paths. +for ac_var in exec_prefix prefix +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* | NONE | '' ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# Be sure to have absolute paths. +for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ + localstatedir libdir includedir oldincludedir infodir mandir +do + eval ac_val=$`echo $ac_var` + case $ac_val in + [\\/$]* | ?:[\\/]* ) ;; + *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; };; + esac +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_confdir=`(dirname "$0") 2>/dev/null || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2 + { (exit 1); exit 1; }; } + else + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } + fi +fi +(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null || + { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2 + { (exit 1); exit 1; }; } +srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'` +ac_env_build_alias_set=${build_alias+set} +ac_env_build_alias_value=$build_alias +ac_cv_env_build_alias_set=${build_alias+set} +ac_cv_env_build_alias_value=$build_alias +ac_env_host_alias_set=${host_alias+set} +ac_env_host_alias_value=$host_alias +ac_cv_env_host_alias_set=${host_alias+set} +ac_cv_env_host_alias_value=$host_alias +ac_env_target_alias_set=${target_alias+set} +ac_env_target_alias_value=$target_alias +ac_cv_env_target_alias_set=${target_alias+set} +ac_cv_env_target_alias_value=$target_alias +ac_env_CC_set=${CC+set} +ac_env_CC_value=$CC +ac_cv_env_CC_set=${CC+set} +ac_cv_env_CC_value=$CC +ac_env_CFLAGS_set=${CFLAGS+set} +ac_env_CFLAGS_value=$CFLAGS +ac_cv_env_CFLAGS_set=${CFLAGS+set} +ac_cv_env_CFLAGS_value=$CFLAGS +ac_env_LDFLAGS_set=${LDFLAGS+set} +ac_env_LDFLAGS_value=$LDFLAGS +ac_cv_env_LDFLAGS_set=${LDFLAGS+set} +ac_cv_env_LDFLAGS_value=$LDFLAGS +ac_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_env_CPPFLAGS_value=$CPPFLAGS +ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set} +ac_cv_env_CPPFLAGS_value=$CPPFLAGS +ac_env_CPP_set=${CPP+set} +ac_env_CPP_value=$CPP +ac_cv_env_CPP_set=${CPP+set} +ac_cv_env_CPP_value=$CPP + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +_ACEOF + + cat <<_ACEOF +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data [PREFIX/share] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --infodir=DIR info documentation [PREFIX/info] + --mandir=DIR man documentation [PREFIX/man] +_ACEOF + + cat <<\_ACEOF + +Program names: + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM run sed PROGRAM on installed program names +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Features: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --disable-dependency-tracking speeds up one-time build + --enable-dependency-tracking do not reject slow dependency extractors + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-pgsql=DIR site header files for PostgreSQL in DIR + +Some influential environment variables: + CC C compiler command + CFLAGS C compiler flags + LDFLAGS linker flags, e.g. -L if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + CPP C preprocessor + +Use these variables to override the choices made by `configure' or to help +it to find libraries and programs with nonstandard names/locations. + +_ACEOF +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + ac_popdir=`pwd` + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d $ac_dir || continue + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + cd $ac_dir + # Check for guested configure; otherwise get Cygnus style configure. + if test -f $ac_srcdir/configure.gnu; then + echo + $SHELL $ac_srcdir/configure.gnu --help=recursive + elif test -f $ac_srcdir/configure; then + echo + $SHELL $ac_srcdir/configure --help=recursive + elif test -f $ac_srcdir/configure.ac || + test -f $ac_srcdir/configure.in; then + echo + $ac_configure --help + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi + cd $ac_popdir + done +fi + +test -n "$ac_init_help" && exit 0 +if $ac_init_version; then + cat <<\_ACEOF + +Copyright (C) 2003 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit 0 +fi +exec 5>config.log +cat >&5 <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + $ $0 $@ + +_ACEOF +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +hostinfo = `(hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_sep= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" + # Get rid of the leading space. + ac_sep=" " + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Be sure not to use single quotes in there, as some shells, +# such as our DU 5.0 friend, will then `close' the trap. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +{ + (set) 2>&1 | + case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in + *ac_space=\ *) + sed -n \ + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + ;; + *) + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------- ## +## Output files. ## +## ------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=$`echo $ac_var` + echo "$ac_var='"'"'$ac_val'"'"'" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + sed "/^$/d" confdefs.h | sort + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core && + rm -rf conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status + ' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo >confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . $cache_file;; + *) . ./$cache_file;; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in `(set) 2>&1 | + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val="\$ac_cv_env_${ac_var}_value" + eval ac_new_val="\$ac_env_${ac_var}_value" + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*) + ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. +set dummy ${ac_tool_prefix}gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. +set dummy ${ac_tool_prefix}cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_CC"; then + ac_ct_CC=$CC + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + CC=$ac_ct_CC +else + CC="$ac_cv_prog_CC" +fi + +fi +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + ac_prog_rejected=no +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# != 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" + fi +fi +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$CC"; then + if test -n "$ac_tool_prefix"; then + for ac_prog in cl + do + # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. +set dummy $ac_tool_prefix$ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +CC=$ac_cv_prog_CC +if test -n "$CC"; then + echo "$as_me:$LINENO: result: $CC" >&5 +echo "${ECHO_T}$CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$CC" && break + done +fi +if test -z "$CC"; then + ac_ct_CC=$CC + for ac_prog in cl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_CC+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_CC"; then + ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +ac_ct_CC=$ac_cv_prog_ac_ct_CC +if test -n "$ac_ct_CC"; then + echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +echo "${ECHO_T}$ac_ct_CC" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$ac_ct_CC" && break +done + + CC=$ac_ct_CC +fi + +fi + + +test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&5 +echo "$as_me: error: no acceptable C compiler found in \$PATH +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + +# Provide some information about the compiler. +echo "$as_me:$LINENO:" \ + "checking for C compiler version" >&5 +ac_compiler=`set X $ac_compile; echo $2` +{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files a.out a.exe b.out" +# Try to create an executable without -o first, disregard a.out. +# It will help us diagnose broken compilers, and finding out an intuition +# of exeext. +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 +ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` +if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 + (eval $ac_link_default) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # Find the output, starting from the most likely. This scheme is +# not robust to junk in `.', hence go to wildcards (a.*) only as a last +# resort. + +# Be careful to initialize this variable, since it used to be cached. +# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile. +ac_cv_exeext= +# b.out is created by i960 compilers. +for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out +do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) + ;; + conftest.$ac_ext ) + # This is the source file. + ;; + [ab].out ) + # We found the default executable, but exeext='' is most + # certainly right. + break;; + *.* ) + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; + * ) + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +See \`config.log' for more details." >&5 +echo "$as_me: error: C compiler cannot create executables +See \`config.log' for more details." >&2;} + { (exit 77); exit 77; }; } +fi + +ac_exeext=$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6 + +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6 +# FIXME: These cross compiler hacks should be removed for Autoconf 3.0 +# If not cross compiling, check that we can run a simple program. +if test "$cross_compiling" != yes; then + if { ac_try='./$ac_file' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + cross_compiling=no + else + if test "$cross_compiling" = maybe; then + cross_compiling=yes + else + { { echo "$as_me:$LINENO: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot run C compiled programs. +If you meant to cross compile, use \`--host'. +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } + fi + fi +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + +rm -f a.out a.exe conftest$ac_cv_exeext b.out +ac_clean_files=$ac_clean_files_save +# Check the compiler produces executables we can run. If not, either +# the compiler is broken, or we cross compile. +echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6 +echo "$as_me:$LINENO: result: $cross_compiling" >&5 +echo "${ECHO_T}$cross_compiling" >&6 + +echo "$as_me:$LINENO: checking for suffix of executables" >&5 +echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6 +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + # If both `conftest.exe' and `conftest' are `present' (well, observable) +# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will +# work properly (i.e., refer to `conftest.exe'), while it won't with +# `rm'. +for ac_file in conftest.exe conftest conftest.*; do + test -f "$ac_file" || continue + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; + *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + export ac_cv_exeext + break;; + * ) break;; + esac +done +else + { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest$ac_cv_exeext +echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +echo "${ECHO_T}$ac_cv_exeext" >&6 + +rm -f conftest.$ac_ext +EXEEXT=$ac_cv_exeext +ac_exeext=$EXEEXT +echo "$as_me:$LINENO: checking for suffix of object files" >&5 +echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6 +if test "${ac_cv_objext+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.o conftest.obj +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do + case $ac_file in + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;; + *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` + break;; + esac +done +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&5 +echo "$as_me: error: cannot compute suffix of object files: cannot compile +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +rm -f conftest.$ac_cv_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +echo "${ECHO_T}$ac_cv_objext" >&6 +OBJEXT=$ac_cv_objext +ac_objext=$OBJEXT +echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6 +if test "${ac_cv_c_compiler_gnu+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +#ifndef __GNUC__ + choke me +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_compiler_gnu=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_compiler_gnu=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_cv_c_compiler_gnu=$ac_compiler_gnu + +fi +echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6 +GCC=`test $ac_compiler_gnu = yes && echo yes` +ac_test_CFLAGS=${CFLAGS+set} +ac_save_CFLAGS=$CFLAGS +CFLAGS="-g" +echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_g+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_g=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_prog_cc_g=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS=$ac_save_CFLAGS +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi +echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5 +echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6 +if test "${ac_cv_prog_cc_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_cv_prog_cc_stdc=no +ac_save_CC=$CC +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ +struct buf { int x; }; +FILE * (*rcsopen) (struct buf *, struct stat *, int); +static char *e (p, i) + char **p; + int i; +{ + return p[i]; +} +static char *f (char * (*g) (char **, int), char **p, ...) +{ + char *s; + va_list v; + va_start (v,p); + s = g (p, va_arg (v,int)); + va_end (v); + return s; +} + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + +int test (int i, double x); +struct s1 {int (*f) (int a);}; +struct s2 {int (*f) (double a);}; +int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); +int argc; +char **argv; +int +main () +{ +return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; + ; + return 0; +} +_ACEOF +# Don't try gcc -ansi; that turns off useful extensions and +# breaks some systems' header files. +# AIX -qlanglvl=ansi +# Ultrix and OSF/1 -std1 +# HP-UX 10.20 and later -Ae +# HP-UX older versions -Aa -D_HPUX_SOURCE +# SVR4 -Xc -D__EXTENSIONS__ +for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" +do + CC="$ac_save_CC $ac_arg" + rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_cc_stdc=$ac_arg +break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext +done +rm -f conftest.$ac_ext conftest.$ac_objext +CC=$ac_save_CC + +fi + +case "x$ac_cv_prog_cc_stdc" in + x|xno) + echo "$as_me:$LINENO: result: none needed" >&5 +echo "${ECHO_T}none needed" >&6 ;; + *) + echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5 +echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6 + CC="$CC $ac_cv_prog_cc_stdc" ;; +esac + +# Some people use a C++ compiler to compile C. Since we use `exit', +# in C++ we need to declare it. In case someone uses the same compiler +# for both compiling C and C++ we need to have the C++ compiler decide +# the declaration of exit, since it's the most demanding environment. +cat >conftest.$ac_ext <<_ACEOF +#ifndef __cplusplus + choke me +#endif +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + for ac_declaration in \ + '' \ + 'extern "C" void std::exit (int) throw (); using std::exit;' \ + 'extern "C" void std::exit (int); using std::exit;' \ + 'extern "C" void exit (int) throw ();' \ + 'extern "C" void exit (int);' \ + 'void exit (int);' +do + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +#include +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +continue +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_declaration +int +main () +{ +exit (42); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + break +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +done +rm -f conftest* +if test -n "$ac_declaration"; then + echo '#ifdef __cplusplus' >>confdefs.h + echo $ac_declaration >>confdefs.h + echo '#endif' >>confdefs.h +fi + +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +am__api_version="1.9" +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f $ac_dir/shtool; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5 +echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;} + { (exit 1); exit 1; }; } +fi +ac_config_guess="$SHELL $ac_aux_dir/config.guess" +ac_config_sub="$SHELL $ac_aux_dir/config.sub" +ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL=$ac_install_sh + fi +fi +echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo "$as_me:$LINENO: checking whether build environment is sane" >&5 +echo $ECHO_N "checking whether build environment is sane... $ECHO_C" >&6 +# Just in case +sleep 1 +echo timestamp > conftest.file +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftest.file` + fi + rm -f conftest.file + if test "$*" != "X $srcdir/configure conftest.file" \ + && test "$*" != "X conftest.file $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { { echo "$as_me:$LINENO: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&5 +echo "$as_me: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" >&2;} + { (exit 1); exit 1; }; } + fi + + test "$2" = conftest.file + ) +then + # Ok. + : +else + { { echo "$as_me:$LINENO: error: newly created file is older than distributed files! +Check your system clock" >&5 +echo "$as_me: error: newly created file is older than distributed files! +Check your system clock" >&2;} + { (exit 1); exit 1; }; } +fi +echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 +test "$program_prefix" != NONE && + program_transform_name="s,^,$program_prefix,;$program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$,$program_suffix,;$program_transform_name" +# Double any \ or $. echo might interpret backslashes. +# By default was `s,x,x', remove it if useless. +cat <<\_ACEOF >conftest.sed +s/[\\$]/&&/g;s/;s,x,x,$// +_ACEOF +program_transform_name=`echo $program_transform_name | sed -f conftest.sed` +rm conftest.sed + +# expand $ac_aux_dir to an absolute path +am_aux_dir=`cd $ac_aux_dir && pwd` + +test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing" +# Use eval to expand $SHELL +if eval "$MISSING --run true"; then + am_missing_run="$MISSING --run " +else + am_missing_run= + { echo "$as_me:$LINENO: WARNING: \`missing' script is too old or missing" >&5 +echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;} +fi + +if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then + # We used to keeping the `.' as first argument, in order to + # allow $(mkdir_p) to be used without argument. As in + # $(mkdir_p) $(somedir) + # where $(somedir) is conditionally defined. However this is wrong + # for two reasons: + # 1. if the package is installed by a user who cannot write `.' + # make install will fail, + # 2. the above comment should most certainly read + # $(mkdir_p) $(DESTDIR)$(somedir) + # so it does not work when $(somedir) is undefined and + # $(DESTDIR) is not. + # To support the latter case, we have to write + # test -z "$(somedir)" || $(mkdir_p) $(DESTDIR)$(somedir), + # so the `.' trick is pointless. + mkdir_p='mkdir -p --' +else + # On NextStep and OpenStep, the `mkdir' command does not + # recognize any option. It will interpret all options as + # directories to create, and then abort because `.' already + # exists. + for d in ./-p ./--version; + do + test -d $d && rmdir $d + done + # $(mkinstalldirs) is defined by Automake if mkinstalldirs exists. + if test -f "$ac_aux_dir/mkinstalldirs"; then + mkdir_p='$(mkinstalldirs)' + else + mkdir_p='$(install_sh) -d' + fi +fi + +for ac_prog in gawk mawk nawk awk +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_AWK+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$AWK"; then + ac_cv_prog_AWK="$AWK" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_AWK="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +AWK=$ac_cv_prog_AWK +if test -n "$AWK"; then + echo "$as_me:$LINENO: result: $AWK" >&5 +echo "${ECHO_T}$AWK" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$AWK" && break +done + +echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 +echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` +if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.make <<\_ACEOF +all: + @echo 'ac_maketemp="$(MAKE)"' +_ACEOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftest.make 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftest.make +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6 + SET_MAKE= +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +rm -rf .tst 2>/dev/null +mkdir .tst 2>/dev/null +if test -d .tst; then + am__leading_dot=. +else + am__leading_dot=_ +fi +rmdir .tst 2>/dev/null + +DEPDIR="${am__leading_dot}deps" + + ac_config_commands="$ac_config_commands depfiles" + + +am_make=${MAKE-make} +cat > confinc << 'END' +am__doit: + @echo done +.PHONY: am__doit +END +# If we don't find an include directive, just comment out the code. +echo "$as_me:$LINENO: checking for style of include used by $am_make" >&5 +echo $ECHO_N "checking for style of include used by $am_make... $ECHO_C" >&6 +am__include="#" +am__quote= +_am_result=none +# First try GNU make style include. +echo "include confinc" > confmf +# We grep out `Entering directory' and `Leaving directory' +# messages which can occur if `w' ends up in MAKEFLAGS. +# In particular we don't look at `^make:' because GNU make might +# be invoked under some other name (usually "gmake"), in which +# case it prints its new name instead of `make'. +if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then + am__include=include + am__quote= + _am_result=GNU +fi +# Now try BSD make style include. +if test "$am__include" = "#"; then + echo '.include "confinc"' > confmf + if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then + am__include=.include + am__quote="\"" + _am_result=BSD + fi +fi + + +echo "$as_me:$LINENO: result: $_am_result" >&5 +echo "${ECHO_T}$_am_result" >&6 +rm -f confinc confmf + +# Check whether --enable-dependency-tracking or --disable-dependency-tracking was given. +if test "${enable_dependency_tracking+set}" = set; then + enableval="$enable_dependency_tracking" + +fi; +if test "x$enable_dependency_tracking" != xno; then + am_depcomp="$ac_aux_dir/depcomp" + AMDEPBACKSLASH='\' +fi + + +if test "x$enable_dependency_tracking" != xno; then + AMDEP_TRUE= + AMDEP_FALSE='#' +else + AMDEP_TRUE='#' + AMDEP_FALSE= +fi + + + +# test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && + test -f $srcdir/config.status; then + { { echo "$as_me:$LINENO: error: source directory already configured; run \"make distclean\" there first" >&5 +echo "$as_me: error: source directory already configured; run \"make distclean\" there first" >&2;} + { (exit 1); exit 1; }; } +fi + +# test whether we have cygpath +if test -z "$CYGPATH_W"; then + if (cygpath --version) >/dev/null 2>/dev/null; then + CYGPATH_W='cygpath -w' + else + CYGPATH_W=echo + fi +fi + + +# Define the identity of the package. + PACKAGE=pgpool + VERSION=2.5.1b1 + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE "$PACKAGE" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define VERSION "$VERSION" +_ACEOF + +# Some tools Automake needs. + +ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"} + + +AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"} + + +AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"} + + +AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"} + + +MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} + +install_sh=${install_sh-"$am_aux_dir/install-sh"} + +# Installed binaries are usually stripped using `strip' when the user +# run `make install-strip'. However `strip' might not be the right +# tool to use in cross-compilation environments, therefore Automake +# will honor the `STRIP' environment variable to overrule this program. +if test "$cross_compiling" != no; then + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. +set dummy ${ac_tool_prefix}strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$STRIP"; then + ac_cv_prog_STRIP="$STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_STRIP="${ac_tool_prefix}strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +STRIP=$ac_cv_prog_STRIP +if test -n "$STRIP"; then + echo "$as_me:$LINENO: result: $STRIP" >&5 +echo "${ECHO_T}$STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + +fi +if test -z "$ac_cv_prog_STRIP"; then + ac_ct_STRIP=$STRIP + # Extract the first word of "strip", so it can be a program name with args. +set dummy strip; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_STRIP"; then + ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_STRIP="strip" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + + test -z "$ac_cv_prog_ac_ct_STRIP" && ac_cv_prog_ac_ct_STRIP=":" +fi +fi +ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP +if test -n "$ac_ct_STRIP"; then + echo "$as_me:$LINENO: result: $ac_ct_STRIP" >&5 +echo "${ECHO_T}$ac_ct_STRIP" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + STRIP=$ac_ct_STRIP +else + STRIP="$ac_cv_prog_STRIP" +fi + +fi +INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s" + +# We need awk for the "check" target. The system "awk" is bad on +# some platforms. +# Always define AMTAR for backward compatibility. + +AMTAR=${AMTAR-"${am_missing_run}tar"} + +am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' + + + + +depcc="$CC" am_compiler_list= + +echo "$as_me:$LINENO: checking dependency style of $depcc" >&5 +echo $ECHO_N "checking dependency style of $depcc... $ECHO_C" >&6 +if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then + # We make a subdir and do the tests there. Otherwise we can end up + # making bogus files that we don't know about and never remove. For + # instance it was reported that on HP-UX the gcc test will end up + # making a dummy file named `D' -- because `-MD' means `put the output + # in D'. + mkdir conftest.dir + # Copy depcomp to subdir because otherwise we won't find it if we're + # using a relative directory. + cp "$am_depcomp" conftest.dir + cd conftest.dir + # We will build objects and dependencies in a subdirectory because + # it helps to detect inapplicable dependency modes. For instance + # both Tru64's cc and ICC support -MD to output dependencies as a + # side effect of compilation, but ICC will put the dependencies in + # the current directory while Tru64 will put them in the object + # directory. + mkdir sub + + am_cv_CC_dependencies_compiler_type=none + if test "$am_compiler_list" = ""; then + am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp` + fi + for depmode in $am_compiler_list; do + # Setup a source with many dependencies, because some compilers + # like to wrap large dependency lists on column 80 (with \), and + # we should not choose a depcomp mode which is confused by this. + # + # We need to recreate these files for each test, as the compiler may + # overwrite some of them when testing with obscure command lines. + # This happens at least with the AIX C compiler. + : > sub/conftest.c + for i in 1 2 3 4 5 6; do + echo '#include "conftst'$i'.h"' >> sub/conftest.c + # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with + # Solaris 8's {/usr,}/bin/sh. + touch sub/conftst$i.h + done + echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf + + case $depmode in + nosideeffect) + # after this tag, mechanisms are not by side-effect, so they'll + # only be used when explicitly requested + if test "x$enable_dependency_tracking" = xyes; then + continue + else + break + fi + ;; + none) break ;; + esac + # We check with `-c' and `-o' for the sake of the "dashmstdout" + # mode. It turns out that the SunPro C++ compiler does not properly + # handle `-M -o', and we need to detect this. + if depmode=$depmode \ + source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \ + depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \ + $SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \ + >/dev/null 2>conftest.err && + grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 && + grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 && + ${MAKE-make} -s -f confmf > /dev/null 2>&1; then + # icc doesn't choke on unknown options, it will just issue warnings + # or remarks (even with -Werror). So we grep stderr for any message + # that says an option was ignored or not supported. + # When given -MP, icc 7.0 and 7.1 complain thusly: + # icc: Command line warning: ignoring option '-M'; no argument required + # The diagnosis changed in icc 8.0: + # icc: Command line remark: option '-MP' not supported + if (grep 'ignoring option' conftest.err || + grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else + am_cv_CC_dependencies_compiler_type=$depmode + break + fi + fi + done + + cd .. + rm -rf conftest.dir +else + am_cv_CC_dependencies_compiler_type=none +fi + +fi +echo "$as_me:$LINENO: result: $am_cv_CC_dependencies_compiler_type" >&5 +echo "${ECHO_T}$am_cv_CC_dependencies_compiler_type" >&6 +CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type + + + +if + test "x$enable_dependency_tracking" != xno \ + && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then + am__fastdepCC_TRUE= + am__fastdepCC_FALSE='#' +else + am__fastdepCC_TRUE='#' + am__fastdepCC_FALSE= +fi + + + + + +for ac_prog in flex lex +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6 +if test "${ac_cv_prog_LEX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$LEX"; then + ac_cv_prog_LEX="$LEX" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_LEX="$ac_prog" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done + +fi +fi +LEX=$ac_cv_prog_LEX +if test -n "$LEX"; then + echo "$as_me:$LINENO: result: $LEX" >&5 +echo "${ECHO_T}$LEX" >&6 +else + echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6 +fi + + test -n "$LEX" && break +done +test -n "$LEX" || LEX=":" + +if test -z "$LEXLIB" +then + echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 +echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6 +if test "${ac_cv_lib_fl_yywrap+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lfl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char yywrap (); +int +main () +{ +yywrap (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_fl_yywrap=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_fl_yywrap=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6 +if test $ac_cv_lib_fl_yywrap = yes; then + LEXLIB="-lfl" +else + echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 +echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6 +if test "${ac_cv_lib_l_yywrap+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ll $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char yywrap (); +int +main () +{ +yywrap (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_l_yywrap=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_l_yywrap=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6 +if test $ac_cv_lib_l_yywrap = yes; then + LEXLIB="-ll" +fi + +fi + +fi + +if test "x$LEX" != "x:"; then + echo "$as_me:$LINENO: checking lex output file root" >&5 +echo $ECHO_N "checking lex output file root... $ECHO_C" >&6 +if test "${ac_cv_prog_lex_root+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # The minimal lex program is just a single line: %%. But some broken lexes +# (Solaris, I think it was) want two %% lines, so accommodate them. +cat >conftest.l <<_ACEOF +%% +%% +_ACEOF +{ (eval echo "$as_me:$LINENO: \"$LEX conftest.l\"") >&5 + (eval $LEX conftest.l) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 +echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} + { (exit 1); exit 1; }; } +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_root" >&6 +rm -f conftest.l +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root + +echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 +echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6 +if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # POSIX says lex can declare yytext either as a pointer or an array; the +# default is implementation-dependent. Figure out which it is, since +# not all implementations provide the %pointer and %array declarations. +ac_cv_prog_lex_yytext_pointer=no +echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c +ac_save_LIBS=$LIBS +LIBS="$LIBS $LEXLIB" +cat >conftest.$ac_ext <<_ACEOF +`cat $LEX_OUTPUT_ROOT.c` +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_prog_lex_yytext_pointer=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_save_LIBS +rm -f "${LEX_OUTPUT_ROOT}.c" + +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_yytext_pointer" >&6 +if test $ac_cv_prog_lex_yytext_pointer = yes; then + +cat >>confdefs.h <<\_ACEOF +#define YYTEXT_POINTER 1 +_ACEOF + +fi + +fi +if test "$LEX" = :; then + LEX=${am_missing_run}flex +fi + + +echo "$as_me:$LINENO: checking for main in -lm" >&5 +echo $ECHO_N "checking for main in -lm... $ECHO_C" >&6 +if test "${ac_cv_lib_m_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lm $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_m_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_m_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_m_main" >&5 +echo "${ECHO_T}$ac_cv_lib_m_main" >&6 +if test $ac_cv_lib_m_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBM 1 +_ACEOF + + LIBS="-lm $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lnsl" >&5 +echo $ECHO_N "checking for main in -lnsl... $ECHO_C" >&6 +if test "${ac_cv_lib_nsl_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lnsl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_nsl_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_nsl_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_main" >&5 +echo "${ECHO_T}$ac_cv_lib_nsl_main" >&6 +if test $ac_cv_lib_nsl_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBNSL 1 +_ACEOF + + LIBS="-lnsl $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lsocket" >&5 +echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6 +if test "${ac_cv_lib_socket_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lsocket $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_socket_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_socket_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 +echo "${ECHO_T}$ac_cv_lib_socket_main" >&6 +if test $ac_cv_lib_socket_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBSOCKET 1 +_ACEOF + + LIBS="-lsocket $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lipc" >&5 +echo $ECHO_N "checking for main in -lipc... $ECHO_C" >&6 +if test "${ac_cv_lib_ipc_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lipc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_ipc_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_ipc_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_ipc_main" >&5 +echo "${ECHO_T}$ac_cv_lib_ipc_main" >&6 +if test $ac_cv_lib_ipc_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBIPC 1 +_ACEOF + + LIBS="-lipc $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lIPC" >&5 +echo $ECHO_N "checking for main in -lIPC... $ECHO_C" >&6 +if test "${ac_cv_lib_IPC_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lIPC $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_IPC_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_IPC_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_IPC_main" >&5 +echo "${ECHO_T}$ac_cv_lib_IPC_main" >&6 +if test $ac_cv_lib_IPC_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBIPC 1 +_ACEOF + + LIBS="-lIPC $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -llc" >&5 +echo $ECHO_N "checking for main in -llc... $ECHO_C" >&6 +if test "${ac_cv_lib_lc_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-llc $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_lc_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_lc_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_lc_main" >&5 +echo "${ECHO_T}$ac_cv_lib_lc_main" >&6 +if test $ac_cv_lib_lc_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBLC 1 +_ACEOF + + LIBS="-llc $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lcompat" >&5 +echo $ECHO_N "checking for main in -lcompat... $ECHO_C" >&6 +if test "${ac_cv_lib_compat_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lcompat $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_compat_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_compat_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_compat_main" >&5 +echo "${ECHO_T}$ac_cv_lib_compat_main" >&6 +if test $ac_cv_lib_compat_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBCOMPAT 1 +_ACEOF + + LIBS="-lcompat $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lBSD" >&5 +echo $ECHO_N "checking for main in -lBSD... $ECHO_C" >&6 +if test "${ac_cv_lib_BSD_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lBSD $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_BSD_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_BSD_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_BSD_main" >&5 +echo "${ECHO_T}$ac_cv_lib_BSD_main" >&6 +if test $ac_cv_lib_BSD_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBBSD 1 +_ACEOF + + LIBS="-lBSD $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lgen" >&5 +echo $ECHO_N "checking for main in -lgen... $ECHO_C" >&6 +if test "${ac_cv_lib_gen_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lgen $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_gen_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_gen_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_gen_main" >&5 +echo "${ECHO_T}$ac_cv_lib_gen_main" >&6 +if test $ac_cv_lib_gen_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBGEN 1 +_ACEOF + + LIBS="-lgen $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lPW" >&5 +echo $ECHO_N "checking for main in -lPW... $ECHO_C" >&6 +if test "${ac_cv_lib_PW_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lPW $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_PW_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_PW_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_PW_main" >&5 +echo "${ECHO_T}$ac_cv_lib_PW_main" >&6 +if test $ac_cv_lib_PW_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBPW 1 +_ACEOF + + LIBS="-lPW $LIBS" + +fi + + +echo "$as_me:$LINENO: checking for main in -lresolv" >&5 +echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6 +if test "${ac_cv_lib_resolv_main+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lresolv $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + + +int +main () +{ +main (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_lib_resolv_main=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_lib_resolv_main=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5 +echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6 +if test $ac_cv_lib_resolv_main = yes; then + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBRESOLV 1 +_ACEOF + + LIBS="-lresolv $LIBS" + +fi + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu +echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then + if test "${ac_cv_prog_CPP+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # Double quotes because CPP needs to be expanded + for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" + do + ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + break +fi + + done + ac_cv_prog_CPP=$CPP + +fi + CPP=$ac_cv_prog_CPP +else + ac_cv_prog_CPP=$CPP +fi +echo "$as_me:$LINENO: result: $CPP" >&5 +echo "${ECHO_T}$CPP" >&6 +ac_preproc_ok=false +for ac_c_preproc_warn_flag in '' yes +do + # Use a header file that comes with gcc, so configuring glibc + # with a fresh cross-compiler works. + # Prefer to if __STDC__ is defined, since + # exists even on freestanding compilers. + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. "Syntax error" is here to catch this case. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#ifdef __STDC__ +# include +#else +# include +#endif + Syntax error +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + : +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Broken: fails on valid input. +continue +fi +rm -f conftest.err conftest.$ac_ext + + # OK, works on sane cases. Now check whether non-existent headers + # can be detected and how. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + # Broken: success on invalid input. +continue +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + # Passes both tests. +ac_preproc_ok=: +break +fi +rm -f conftest.err conftest.$ac_ext + +done +# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. +rm -f conftest.err conftest.$ac_ext +if $ac_preproc_ok; then + : +else + { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&5 +echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +See \`config.log' for more details." >&2;} + { (exit 1); exit 1; }; } +fi + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + +echo "$as_me:$LINENO: checking for egrep" >&5 +echo $ECHO_N "checking for egrep... $ECHO_C" >&6 +if test "${ac_cv_prog_egrep+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if echo a | (grep -E '(a|b)') >/dev/null 2>&1 + then ac_cv_prog_egrep='grep -E' + else ac_cv_prog_egrep='egrep' + fi +fi +echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5 +echo "${ECHO_T}$ac_cv_prog_egrep" >&6 + EGREP=$ac_cv_prog_egrep + + +echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6 +if test "${ac_cv_header_stdc+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_stdc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_stdc=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "memchr" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "free" >/dev/null 2>&1; then + : +else + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. + if test "$cross_compiling" = yes; then + : +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#if ((' ' & 0x0FF) == 0x020) +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) \ + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif + +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int +main () +{ + int i; + for (i = 0; i < 256; i++) + if (XOR (islower (i), ISLOWER (i)) + || toupper (i) != TOUPPER (i)) + exit(2); + exit (0); +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + : +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_header_stdc=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +echo "${ECHO_T}$ac_cv_header_stdc" >&6 +if test $ac_cv_header_stdc = yes; then + +cat >>confdefs.h <<\_ACEOF +#define STDC_HEADERS 1 +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for sys/wait.h that is POSIX.1 compatible" >&5 +echo $ECHO_N "checking for sys/wait.h that is POSIX.1 compatible... $ECHO_C" >&6 +if test "${ac_cv_header_sys_wait_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifndef WEXITSTATUS +# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) +#endif +#ifndef WIFEXITED +# define WIFEXITED(stat_val) (((stat_val) & 255) == 0) +#endif + +int +main () +{ + int s; + wait (&s); + s = WIFEXITED (s) ? WEXITSTATUS (s) : 1; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_sys_wait_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_sys_wait_h=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5 +echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6 +if test $ac_cv_header_sys_wait_h = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_SYS_WAIT_H 1 +_ACEOF + +fi + +# On IRIX 5.3, sys/types and inttypes.h are conflicting. + + + + + + + + + +for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ + inttypes.h stdint.h unistd.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default + +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_Header=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_Header=no" +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + + + + + + +for ac_header in fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h sys/param.h sys/types.h sys/time.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 +else + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_header_compiler=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( + cat <<\_ASBOX +## ------------------------------------------ ## +## Report this to the AC_PACKAGE_NAME lists. ## +## ------------------------------------------ ## +_ASBOX + ) | + sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + +echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6 +if test "${ac_cv_c_const+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ +/* FIXME: Include the comments suggested by Paul. */ +#ifndef __cplusplus + /* Ultrix mips cc rejects this. */ + typedef int charset[2]; + const charset x; + /* SunOS 4.1.1 cc rejects this. */ + char const *const *ccp; + char **p; + /* NEC SVR4.0.2 mips cc rejects this. */ + struct point {int x, y;}; + static struct point const zero = {0,0}; + /* AIX XL C 1.02.0.0 rejects this. + It does not let you subtract one const X* pointer from another in + an arm of an if-expression whose if-part is not a constant + expression */ + const char *g = "string"; + ccp = &g + (g ? g-g : 0); + /* HPUX 7.0 cc rejects these. */ + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; + { /* SCO 3.2v4 cc rejects this. */ + char *t; + char const *s = 0 ? (char *) 0 : (char const *) 0; + + *t++ = 0; + } + { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ + int x[] = {25, 17}; + const int *foo = &x[0]; + ++foo; + } + { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ + typedef const int *iptr; + iptr p = 0; + ++p; + } + { /* AIX XL C 1.02.0.0 rejects this saying + "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ + struct s { int j; const int *ap[3]; }; + struct s *b; b->j = 5; + } + { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ + const int foo = 10; + } +#endif + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_c_const=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_c_const=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +echo "${ECHO_T}$ac_cv_c_const" >&6 +if test $ac_cv_c_const = no; then + +cat >>confdefs.h <<\_ACEOF +#define const +_ACEOF + +fi + +echo "$as_me:$LINENO: checking for pid_t" >&5 +echo $ECHO_N "checking for pid_t... $ECHO_C" >&6 +if test "${ac_cv_type_pid_t+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if ((pid_t *) 0) + return 0; +if (sizeof (pid_t)) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_pid_t=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_pid_t=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5 +echo "${ECHO_T}$ac_cv_type_pid_t" >&6 +if test $ac_cv_type_pid_t = yes; then + : +else + +cat >>confdefs.h <<_ACEOF +#define pid_t int +_ACEOF + +fi + +echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6 +if test "${ac_cv_header_time+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include + +int +main () +{ +if ((struct tm *) 0) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_header_time=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_header_time=no +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +echo "${ECHO_T}$ac_cv_header_time" >&6 +if test $ac_cv_header_time = yes; then + +cat >>confdefs.h <<\_ACEOF +#define TIME_WITH_SYS_TIME 1 +_ACEOF + +fi + + +echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6 +if test "${ac_cv_type_signal+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#ifdef signal +# undef signal +#endif +#ifdef __cplusplus +extern "C" void (*signal (int, void (*)(int)))(int); +#else +void (*signal ()) (); +#endif + +int +main () +{ +int i; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_type_signal=void +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_type_signal=int +fi +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +echo "${ECHO_T}$ac_cv_type_signal" >&6 + +cat >>confdefs.h <<_ACEOF +#define RETSIGTYPE $ac_cv_type_signal +_ACEOF + + + +for ac_func in vprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +echo "$as_me:$LINENO: checking for _doprnt" >&5 +echo $ECHO_N "checking for _doprnt... $ECHO_C" >&6 +if test "${ac_cv_func__doprnt+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define _doprnt to an innocuous variant, in case declares _doprnt. + For example, HP-UX 11i declares gettimeofday. */ +#define _doprnt innocuous__doprnt + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char _doprnt (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef _doprnt + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char _doprnt (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub__doprnt) || defined (__stub____doprnt) +choke me +#else +char (*f) () = _doprnt; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != _doprnt; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func__doprnt=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +ac_cv_func__doprnt=no +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: $ac_cv_func__doprnt" >&5 +echo "${ECHO_T}$ac_cv_func__doprnt" >&6 +if test $ac_cv_func__doprnt = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_DOPRNT 1 +_ACEOF + +fi + +fi +done + + +echo "$as_me:$LINENO: checking for wait3 that fills in rusage" >&5 +echo $ECHO_N "checking for wait3 that fills in rusage... $ECHO_C" >&6 +if test "${ac_cv_func_wait3_rusage+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test "$cross_compiling" = yes; then + ac_cv_func_wait3_rusage=no +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +#include +#include +#include +/* HP-UX has wait3 but does not fill in rusage at all. */ +int +main () +{ + struct rusage r; + int i; + /* Use a field that we can force nonzero -- + voluntary context switches. + For systems like NeXT and OSF/1 that don't set it, + also use the system CPU time. And page faults (I/O) for Linux. */ + r.ru_nvcsw = 0; + r.ru_stime.tv_sec = 0; + r.ru_stime.tv_usec = 0; + r.ru_majflt = r.ru_minflt = 0; + switch (fork ()) + { + case 0: /* Child. */ + sleep(1); /* Give up the CPU. */ + _exit(0); + break; + case -1: /* What can we do? */ + _exit(0); + break; + default: /* Parent. */ + wait3(&i, 0, &r); + /* Avoid "text file busy" from rm on fast HP-UX machines. */ + sleep(2); + exit (r.ru_nvcsw == 0 && r.ru_majflt == 0 && r.ru_minflt == 0 + && r.ru_stime.tv_sec == 0 && r.ru_stime.tv_usec == 0); + } +} +_ACEOF +rm -f conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { ac_try='./conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + ac_cv_func_wait3_rusage=yes +else + echo "$as_me: program exited with status $ac_status" >&5 +echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +( exit $ac_status ) +ac_cv_func_wait3_rusage=no +fi +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +fi +fi +echo "$as_me:$LINENO: result: $ac_cv_func_wait3_rusage" >&5 +echo "${ECHO_T}$ac_cv_func_wait3_rusage" >&6 +if test $ac_cv_func_wait3_rusage = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_WAIT3 1 +_ACEOF + +fi + + + + + + + + + +for ac_func in setsid select socket sigprocmask strdup strerror strftime asprintf +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6 +if eval "test \"\${$as_ac_var+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any gcc2 internal prototype to avoid an error. */ +#ifdef __cplusplus +extern "C" +{ +#endif +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_$ac_func) || defined (__stub___$ac_func) +choke me +#else +char (*f) () = $ac_func; +#endif +#ifdef __cplusplus +} +#endif + +int +main () +{ +return f != $ac_func; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 + (eval $ac_link) 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest$ac_exeext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; }; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + +eval "$as_ac_var=no" +fi +rm -f conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6 +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + +PGSQL_INCLUDE_DIR=/usr/local/pgsql/include + +# Check whether --with-pgsql or --without-pgsql was given. +if test "${with_pgsql+set}" = set; then + withval="$with_pgsql" + + case "$withval" in + "" | y | ye | yes | n | no) + { { echo "$as_me:$LINENO: error: *** You must supply an argument to the --with-pgsql option." >&5 +echo "$as_me: error: *** You must supply an argument to the --with-pgsql option." >&2;} + { (exit 1); exit 1; }; } + ;; + esac + PGSQL_INCLUDE_DIR="$withval" + +fi; + + + + ac_config_headers="$ac_config_headers config.h" + + + ac_config_files="$ac_config_files Makefile" +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +{ + (set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n \ + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + ;; + esac; +} | + sed ' + t clear + : clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + : end' >>confcache +if diff $cache_file confcache >/dev/null 2>&1; then :; else + if test -w $cache_file; then + test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file" + cat confcache >$cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/; +s/:*\${srcdir}:*/:/; +s/:*@srcdir@:*/:/; +s/^\([^=]*=[ ]*\):*/\1/; +s/:*$//; +s/^[^=]*=[ ]*$//; +}' +fi + +DEFS=-DHAVE_CONFIG_H + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_i=`echo "$ac_i" | + sed 's/\$U\././;s/\.o$//;s/\.obj$//'` + # 2. Add them. + ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + +if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"AMDEP\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi +if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then + { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&5 +echo "$as_me: error: conditional \"am__fastdepCC\" was never defined. +Usually this means the macro was only invoked conditionally." >&2;} + { (exit 1); exit 1; }; } +fi + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be Bourne compatible +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' +elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then + set -o posix +fi +DUALCASE=1; export DUALCASE # for MKS sh + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# Work around bugs in pre-3.0 UWIN ksh. +$as_unset ENV MAIL MAILPATH +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)$' \| \ + . : '\(.\)' 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; } + /^X\/\(\/\/\)$/{ s//\1/; q; } + /^X\/\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + + +# PATH needs CR, and LINENO needs CR and PATH. +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" || { + # Find who we are. Look in the path if we contain no path at all + # relative or not. + case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done + + ;; + esac + # We did not find ourselves, most probably we were run as `sh COMMAND' + # in which case we are not to be found in the path. + if test "x$as_myself" = x; then + as_myself=$0 + fi + if test ! -f "$as_myself"; then + { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5 +echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;} + { (exit 1); exit 1; }; } + fi + case $CONFIG_SHELL in + '') + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for as_base in sh bash ksh sh5; do + case $as_dir in + /*) + if ("$as_dir/$as_base" -c ' + as_lineno_1=$LINENO + as_lineno_2=$LINENO + as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null` + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then + $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; } + $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; } + CONFIG_SHELL=$as_dir/$as_base + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" ${1+"$@"} + fi;; + esac + done +done +;; + esac + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line before each line; the second 'sed' does the real + # work. The second script uses 'N' to pair each line-number line + # with the numbered line, and appends trailing '-' during + # substitution so that $LINENO is not a special case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-) + sed '=' <$as_myself | + sed ' + N + s,$,-, + : loop + s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3, + t loop + s,-$,, + s,^['$as_cr_digits']*\n,, + ' >$as_me.lineno && + chmod +x $as_me.lineno || + { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5 +echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;} + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensible to this). + . ./$as_me.lineno + # Exit status is that of the last command. + exit +} + + +case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in + *c*,-n*) ECHO_N= ECHO_C=' +' ECHO_T=' ' ;; + *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;; + *) ECHO_N= ECHO_C='\c' ECHO_T= ;; +esac + +if expr a : '\(a\)' >/dev/null 2>&1; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + # We could just check for DJGPP; but this test a) works b) is more generic + # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04). + if test -f conf$$.exe; then + # Don't use ln at all; we don't have any links + as_ln_s='cp -p' + else + as_ln_s='ln -s' + fi +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.file + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +as_executable_p="test -f" + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +# IFS +# We need space, tab and new line, in precisely that order. +as_nl=' +' +IFS=" $as_nl" + +# CDPATH. +$as_unset CDPATH + +exec 6>&1 + +# Open the log real soon, to keep \$[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. Logging --version etc. is OK. +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX +} >&5 +cat >&5 <<_CSEOF + +This file was extended by $as_me, which was +generated by GNU Autoconf 2.59. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +_CSEOF +echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5 +echo >&5 +_ACEOF + +# Files that config.status was made for. +if test -n "$ac_config_files"; then + echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_headers"; then + echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_links"; then + echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS +fi + +if test -n "$ac_config_commands"; then + echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS +fi + +cat >>$CONFIG_STATUS <<\_ACEOF + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE + +Configuration files: +$config_files + +Configuration headers: +$config_headers + +Configuration commands: +$config_commands + +Report bugs to ." +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.59, + with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2003 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." +srcdir=$srcdir +INSTALL="$INSTALL" +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "x$1" : 'x\([^=]*\)='` + ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'` + ac_shift=: + ;; + -*) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + *) # This is not an option, so the user has probably given explicit + # arguments. + ac_option=$1 + ac_need_defaults=false;; + esac + + case $ac_option in + # Handling of the options. +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --vers* | -V ) + echo "$ac_cs_version"; exit 0 ;; + --he | --h) + # Conflict between --help and --header + { { echo "$as_me:$LINENO: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: ambiguous option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; };; + --help | --hel | -h ) + echo "$ac_cs_usage"; exit 0 ;; + --debug | --d* | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --header | --heade | --head | --hea ) + $ac_shift + CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + ac_need_defaults=false;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&5 +echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2;} + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# +# INIT-COMMANDS section. +# + +AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" + +_ACEOF + + + +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_config_target in $ac_config_targets +do + case "$ac_config_target" in + # Handling of arguments. + "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "depfiles" ) CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; + "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers + test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason to put it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Create a temporary directory, and hook for its removal unless debugging. +$debug || +{ + trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} + +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./confstat$$-$RANDOM + (umask 077 && mkdir $tmp) +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF + +# +# CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "\$CONFIG_FILES"; then + # Protect against being on the right side of a sed subst in config.status. + sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g; + s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF +s,@SHELL@,$SHELL,;t t +s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t +s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t +s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t +s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t +s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t +s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t +s,@exec_prefix@,$exec_prefix,;t t +s,@prefix@,$prefix,;t t +s,@program_transform_name@,$program_transform_name,;t t +s,@bindir@,$bindir,;t t +s,@sbindir@,$sbindir,;t t +s,@libexecdir@,$libexecdir,;t t +s,@datadir@,$datadir,;t t +s,@sysconfdir@,$sysconfdir,;t t +s,@sharedstatedir@,$sharedstatedir,;t t +s,@localstatedir@,$localstatedir,;t t +s,@libdir@,$libdir,;t t +s,@includedir@,$includedir,;t t +s,@oldincludedir@,$oldincludedir,;t t +s,@infodir@,$infodir,;t t +s,@mandir@,$mandir,;t t +s,@build_alias@,$build_alias,;t t +s,@host_alias@,$host_alias,;t t +s,@target_alias@,$target_alias,;t t +s,@DEFS@,$DEFS,;t t +s,@ECHO_C@,$ECHO_C,;t t +s,@ECHO_N@,$ECHO_N,;t t +s,@ECHO_T@,$ECHO_T,;t t +s,@LIBS@,$LIBS,;t t +s,@CC@,$CC,;t t +s,@CFLAGS@,$CFLAGS,;t t +s,@LDFLAGS@,$LDFLAGS,;t t +s,@CPPFLAGS@,$CPPFLAGS,;t t +s,@ac_ct_CC@,$ac_ct_CC,;t t +s,@EXEEXT@,$EXEEXT,;t t +s,@OBJEXT@,$OBJEXT,;t t +s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t +s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t +s,@INSTALL_DATA@,$INSTALL_DATA,;t t +s,@CYGPATH_W@,$CYGPATH_W,;t t +s,@PACKAGE@,$PACKAGE,;t t +s,@VERSION@,$VERSION,;t t +s,@ACLOCAL@,$ACLOCAL,;t t +s,@AUTOCONF@,$AUTOCONF,;t t +s,@AUTOMAKE@,$AUTOMAKE,;t t +s,@AUTOHEADER@,$AUTOHEADER,;t t +s,@MAKEINFO@,$MAKEINFO,;t t +s,@install_sh@,$install_sh,;t t +s,@STRIP@,$STRIP,;t t +s,@ac_ct_STRIP@,$ac_ct_STRIP,;t t +s,@INSTALL_STRIP_PROGRAM@,$INSTALL_STRIP_PROGRAM,;t t +s,@mkdir_p@,$mkdir_p,;t t +s,@AWK@,$AWK,;t t +s,@SET_MAKE@,$SET_MAKE,;t t +s,@am__leading_dot@,$am__leading_dot,;t t +s,@AMTAR@,$AMTAR,;t t +s,@am__tar@,$am__tar,;t t +s,@am__untar@,$am__untar,;t t +s,@DEPDIR@,$DEPDIR,;t t +s,@am__include@,$am__include,;t t +s,@am__quote@,$am__quote,;t t +s,@AMDEP_TRUE@,$AMDEP_TRUE,;t t +s,@AMDEP_FALSE@,$AMDEP_FALSE,;t t +s,@AMDEPBACKSLASH@,$AMDEPBACKSLASH,;t t +s,@CCDEPMODE@,$CCDEPMODE,;t t +s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t +s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t +s,@LEX@,$LEX,;t t +s,@LEXLIB@,$LEXLIB,;t t +s,@LEX_OUTPUT_ROOT@,$LEX_OUTPUT_ROOT,;t t +s,@CPP@,$CPP,;t t +s,@EGREP@,$EGREP,;t t +s,@PGSQL_INCLUDE_DIR@,$PGSQL_INCLUDE_DIR,;t t +s,@LIBOBJS@,$LIBOBJS,;t t +s,@LTLIBOBJS@,$LTLIBOBJS,;t t +CEOF + +_ACEOF + + cat >>$CONFIG_STATUS <<\_ACEOF + # Split the substitutions into bite-sized pieces for seds with + # small command number limits, like on Digital OSF/1 and HP-UX. + ac_max_sed_lines=48 + ac_sed_frag=1 # Number of current file. + ac_beg=1 # First line for current file. + ac_end=$ac_max_sed_lines # Line after last line for current file. + ac_more_lines=: + ac_sed_cmds= + while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + else + sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag + fi + if test ! -s $tmp/subs.frag; then + ac_more_lines=false + else + # The purpose of the label and of the branching condition is to + # speed up the sed processing (if there are no `@' at all, there + # is no need to browse any of the substitutions). + # These are the two extra sed commands mentioned above. + (echo ':t + /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed" + else + ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed" + fi + ac_sed_frag=`expr $ac_sed_frag + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_lines` + fi + done + if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat + fi +fi # test -n "$CONFIG_FILES" + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories. + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_builddir$INSTALL ;; + esac + + if test x"$ac_file" != x-; then + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + rm -f "$ac_file" + fi + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + configure_input= + else + configure_input="$ac_file. " + fi + configure_input=$configure_input"Generated from `echo $ac_file_in | + sed 's,.*/,,'` by configure." + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s,@configure_input@,$configure_input,;t t +s,@srcdir@,$ac_srcdir,;t t +s,@abs_srcdir@,$ac_abs_srcdir,;t t +s,@top_srcdir@,$ac_top_srcdir,;t t +s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t +s,@builddir@,$ac_builddir,;t t +s,@abs_builddir@,$ac_abs_builddir,;t t +s,@top_builddir@,$ac_top_builddir,;t t +s,@abs_top_builddir@,$ac_abs_top_builddir,;t t +s,@INSTALL@,$ac_INSTALL,;t t +" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out + rm -f $tmp/stdin + if test x"$ac_file" != x-; then + mv $tmp/out $ac_file + else + cat $tmp/out + rm -f $tmp/out + fi + +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_HEADER section. +# + +# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where +# NAME is the cpp macro being defined and VALUE is the value it is being given. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s,^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='[ ].*$,\1#\2' +ac_dC=' ' +ac_dD=',;t' +# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_uA='s,^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='$,\1#\2define\3' +ac_uC=' ' +ac_uD=',;t' + +for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case $ac_file in + - | *:- | *:-:* ) # input from stdin + cat >$tmp/stdin + ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;; + * ) ac_file_in=$ac_file.in ;; + esac + + test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + + # First look for the input files in the build tree, otherwise in the + # src tree. + ac_file_inputs=`IFS=: + for f in $ac_file_in; do + case $f in + -) echo $tmp/stdin ;; + [\\/$]*) + # Absolute (can't be DOS-style, as IFS=:) + test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + # Do quote $f, to prevent DOS paths from being IFS'd. + echo "$f";; + *) # Relative + if test -f "$f"; then + # Build tree + echo "$f" + elif test -f "$srcdir/$f"; then + # Source tree + echo "$srcdir/$f" + else + # /dev/null tree + { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5 +echo "$as_me: error: cannot find input file: $f" >&2;} + { (exit 1); exit 1; }; } + fi;; + esac + done` || { (exit 1); exit 1; } + # Remove the trailing spaces. + sed 's/[ ]*$//' $ac_file_inputs >$tmp/in + +_ACEOF + +# Transform confdefs.h into two sed scripts, `conftest.defines' and +# `conftest.undefs', that substitutes the proper values into +# config.h.in to produce config.h. The first handles `#define' +# templates, and the second `#undef' templates. +# And first: Protect against being on the right side of a sed subst in +# config.status. Protect against being in an unquoted here document +# in config.status. +rm -f conftest.defines conftest.undefs +# Using a here document instead of a string reduces the quoting nightmare. +# Putting comments in sed scripts is not portable. +# +# `end' is used to avoid that the second main sed command (meant for +# 0-ary CPP macros) applies to n-ary macro definitions. +# See the Autoconf documentation for `clear'. +cat >confdef2sed.sed <<\_ACEOF +s/[\\&,]/\\&/g +s,[\\$`],\\&,g +t clear +: clear +s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*\)\(([^)]*)\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp +t end +s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp +: end +_ACEOF +# If some macros were called several times there might be several times +# the same #defines, which is useless. Nevertheless, we may not want to +# sort them, since we want the *last* AC-DEFINE to be honored. +uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines +sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs +rm -f confdef2sed.sed + +# This sed command replaces #undef with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it. +cat >>conftest.undefs <<\_ACEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +_ACEOF + +# Break up conftest.defines because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS +echo ' if grep "^[ ]*#[ ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS +echo ' # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS +echo ' :' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.defines >/dev/null +do + # Write a limited-size here document to $tmp/defines.sed. + echo ' cat >$tmp/defines.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#define' lines. + echo '/^[ ]*#[ ]*define/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/defines.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail + rm -f conftest.defines + mv conftest.tail conftest.defines +done +rm -f conftest.defines +echo ' fi # grep' >>$CONFIG_STATUS +echo >>$CONFIG_STATUS + +# Break up conftest.undefs because some shells have a limit on the size +# of here documents, and old seds have small limits too (100 cmds). +echo ' # Handle all the #undef templates' >>$CONFIG_STATUS +rm -f conftest.tail +while grep . conftest.undefs >/dev/null +do + # Write a limited-size here document to $tmp/undefs.sed. + echo ' cat >$tmp/undefs.sed <>$CONFIG_STATUS + # Speed up: don't consider the non `#undef' + echo '/^[ ]*#[ ]*undef/!b' >>$CONFIG_STATUS + # Work around the forget-to-reset-the-flag bug. + echo 't clr' >>$CONFIG_STATUS + echo ': clr' >>$CONFIG_STATUS + sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS + echo 'CEOF + sed -f $tmp/undefs.sed $tmp/in >$tmp/out + rm -f $tmp/in + mv $tmp/out $tmp/in +' >>$CONFIG_STATUS + sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail + rm -f conftest.undefs + mv conftest.tail conftest.undefs +done +rm -f conftest.undefs + +cat >>$CONFIG_STATUS <<\_ACEOF + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + if test x"$ac_file" = x-; then + echo "/* Generated by configure. */" >$tmp/config.h + else + echo "/* $ac_file. Generated by configure. */" >$tmp/config.h + fi + cat $tmp/in >>$tmp/config.h + rm -f $tmp/in + if test x"$ac_file" != x-; then + if diff $ac_file $tmp/config.h >/dev/null 2>&1; then + { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +echo "$as_me: $ac_file is unchanged" >&6;} + else + ac_dir=`(dirname "$ac_file") 2>/dev/null || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + rm -f $ac_file + mv $tmp/config.h $ac_file + fi + else + cat $tmp/config.h + rm -f $tmp/config.h + fi +# Compute $ac_file's index in $config_headers. +_am_stamp_count=1 +for _am_header in $config_headers :; do + case $_am_header in + $ac_file | $ac_file:* ) + break ;; + * ) + _am_stamp_count=`expr $_am_stamp_count + 1` ;; + esac +done +echo "timestamp for $ac_file" >`(dirname $ac_file) 2>/dev/null || +$as_expr X$ac_file : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X$ac_file : 'X\(//\)[^/]' \| \ + X$ac_file : 'X\(//\)$' \| \ + X$ac_file : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X$ac_file | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'`/stamp-h$_am_stamp_count +done +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF + +# +# CONFIG_COMMANDS section. +# +for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue + ac_dest=`echo "$ac_file" | sed 's,:.*,,'` + ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'` + ac_dir=`(dirname "$ac_dest") 2>/dev/null || +$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_dest" : 'X\(//\)[^/]' \| \ + X"$ac_dest" : 'X\(//\)$' \| \ + X"$ac_dest" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$ac_dest" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p "$ac_dir" + else + as_dir="$ac_dir" + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5 +echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;} + { (exit 1); exit 1; }; }; } + + ac_builddir=. + +if test "$ac_dir" != .; then + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A "../" for each directory in $ac_dir_suffix. + ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'` +else + ac_dir_suffix= ac_top_builddir= +fi + +case $srcdir in + .) # No --srcdir option. We are building in place. + ac_srcdir=. + if test -z "$ac_top_builddir"; then + ac_top_srcdir=. + else + ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'` + fi ;; + [\\/]* | ?:[\\/]* ) # Absolute path. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir ;; + *) # Relative path. + ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_builddir$srcdir ;; +esac + +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + + + { echo "$as_me:$LINENO: executing $ac_dest commands" >&5 +echo "$as_me: executing $ac_dest commands" >&6;} + case $ac_dest in + depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do + # Strip MF so we end up with the name of the file. + mf=`echo "$mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile or not. + # We used to match only the files named `Makefile.in', but + # some people rename them; so instead we look at the file content. + # Grep'ing the first line is not enough: some people post-process + # each Makefile.in and add a new line on top of each file to say so. + # So let's grep whole file. + if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then + dirpart=`(dirname "$mf") 2>/dev/null || +$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$mf" : 'X\(//\)[^/]' \| \ + X"$mf" : 'X\(//\)$' \| \ + X"$mf" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$mf" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + else + continue + fi + # Extract the definition of DEPDIR, am__include, and am__quote + # from the Makefile without running `make'. + DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` + test -z "$DEPDIR" && continue + am__include=`sed -n 's/^am__include = //p' < "$mf"` + test -z "am__include" && continue + am__quote=`sed -n 's/^am__quote = //p' < "$mf"` + # When using ansi2knr, U may be empty or an underscore; expand it + U=`sed -n 's/^U = //p' < "$mf"` + # Find all dependency output files, they are included files with + # $(DEPDIR) in their names. We invoke sed twice because it is the + # simplest approach to changing $(DEPDIR) to its actual value in the + # expansion. + for file in `sed -n " + s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ + sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do + # Make sure the directory exists. + test -f "$dirpart/$file" && continue + fdir=`(dirname "$file") 2>/dev/null || +$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$file" : 'X\(//\)[^/]' \| \ + X"$file" : 'X\(//\)$' \| \ + X"$file" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + { if $as_mkdir_p; then + mkdir -p $dirpart/$fdir + else + as_dir=$dirpart/$fdir + as_dirs= + while test ! -d "$as_dir"; do + as_dirs="$as_dir $as_dirs" + as_dir=`(dirname "$as_dir") 2>/dev/null || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } + /^X\(\/\/\)[^/].*/{ s//\1/; q; } + /^X\(\/\/\)$/{ s//\1/; q; } + /^X\(\/\).*/{ s//\1/; q; } + s/.*/./; q'` + done + test ! -n "$as_dirs" || mkdir $as_dirs + fi || { { echo "$as_me:$LINENO: error: cannot create directory $dirpart/$fdir" >&5 +echo "$as_me: error: cannot create directory $dirpart/$fdir" >&2;} + { (exit 1); exit 1; }; }; } + + # echo "creating $dirpart/$file" + echo '# dummy' > "$dirpart/$file" + done +done + ;; + esac +done +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..670a3d6 --- /dev/null +++ b/configure.in @@ -0,0 +1,56 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT + +dnl Checks for programs. +AC_PROG_CC + +AM_INIT_AUTOMAKE(pgpool, 2.5.1b1) + +AM_PROG_LEX + +dnl Checks for libraries. +AC_CHECK_LIB(m, main) +AC_CHECK_LIB(nsl, main) +AC_CHECK_LIB(socket, main) +AC_CHECK_LIB(ipc, main) +AC_CHECK_LIB(IPC, main) +AC_CHECK_LIB(lc, main) +AC_CHECK_LIB(compat, main) +AC_CHECK_LIB(BSD, main) +AC_CHECK_LIB(gen, main) +AC_CHECK_LIB(PW, main) +AC_CHECK_LIB(resolv, main) + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_SYS_WAIT +AC_CHECK_HEADERS(fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h sys/param.h sys/types.h sys/time.h) + +dnl Checks for typedefs, structures, and compiler characteristics. +AC_C_CONST +AC_TYPE_PID_T +AC_HEADER_TIME + +dnl Checks for library functions. +AC_TYPE_SIGNAL +AC_FUNC_VPRINTF +AC_FUNC_WAIT3 +AC_CHECK_FUNCS(setsid select socket sigprocmask strdup strerror strftime asprintf) + +PGSQL_INCLUDE_DIR=/usr/local/pgsql/include +AC_ARG_WITH(pgsql, + [ --with-pgsql=DIR site header files for PostgreSQL in DIR], + [ + case "$withval" in + "" | y | ye | yes | n | no) + AC_MSG_ERROR([*** You must supply an argument to the --with-pgsql option.]) + ;; + esac + PGSQL_INCLUDE_DIR="$withval" + ]) + +AC_SUBST(PGSQL_INCLUDE_DIR) + +AM_CONFIG_HEADER(config.h) + +AC_OUTPUT(Makefile) diff --git a/depcomp b/depcomp new file mode 100755 index 0000000..11e2d3b --- /dev/null +++ b/depcomp @@ -0,0 +1,522 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2004-05-31.23 + +# Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try \`$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by `PROGRAMS ARGS'. + object Object file output by `PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputing dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit 0 + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit 0 + ;; +esac + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. + "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz +## The second -e expression handles DOS-style file names with drive letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the `deleted header file' problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. + tr ' ' ' +' < "$tmpdepfile" | +## Some versions of gcc put a space before the `:'. On the theory +## that the space means something, we add a space to the output as +## well. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like `#:fec' to the end of the + # dependency line. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ + tr ' +' ' ' >> $depfile + echo >> $depfile + + # The second pass generates a dummy entry for each header file. + tr ' ' ' +' < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> $depfile + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts `$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` + tmpdepfile="$stripped.u" + if test "$libtool" = yes; then + "$@" -Wc,-M + else + "$@" -M + fi + stat=$? + + if test -f "$tmpdepfile"; then : + else + stripped=`echo "$stripped" | sed 's,^.*/,,'` + tmpdepfile="$stripped.u" + fi + + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + + if test -f "$tmpdepfile"; then + outname="$stripped.o" + # Each line is of the form `foo.o: dependent.h'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" + sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" + else + # The sourcefile does not contain any dependencies, so just + # store a dummy comment line, to avoid errors with the Makefile + # "include basename.Plo" scheme. + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +icc) + # Intel's C compiler understands `-MD -MF file'. However on + # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c + # ICC 7.0 will fill foo.d with something like + # foo.o: sub/foo.c + # foo.o: sub/foo.h + # which is wrong. We want: + # sub/foo.o: sub/foo.c + # sub/foo.o: sub/foo.h + # sub/foo.c: + # sub/foo.h: + # ICC 7.1 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using \ : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | + sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in `foo.d' instead, so we check for that too. + # Subdirectories are respected. + dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` + test "x$dir" = "x$object" && dir= + base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` + + if test "$libtool" = yes; then + # Dependencies are output in .lo.d with libtool 1.4. + # With libtool 1.5 they are output both in $dir.libs/$base.o.d + # and in $dir.libs/$base.o.d and $dir$base.o.d. We process the + # latter, because the former will be cleaned when $dir.libs is + # erased. + tmpdepfile1="$dir.libs/$base.lo.d" + tmpdepfile2="$dir$base.o.d" + tmpdepfile3="$dir.libs/$base.d" + "$@" -Wc,-MD + else + tmpdepfile1="$dir$base.o.d" + tmpdepfile2="$dir$base.d" + tmpdepfile3="$dir$base.d" + "$@" -MD + fi + + stat=$? + if test $stat -eq 0; then : + else + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + if test -f "$tmpdepfile1"; then + tmpdepfile="$tmpdepfile1" + elif test -f "$tmpdepfile2"; then + tmpdepfile="$tmpdepfile2" + else + tmpdepfile="$tmpdepfile3" + fi + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" + # That's a tab and a space in the []. + sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" + else + echo "#dummy" > "$depfile" + fi + rm -f "$tmpdepfile" + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for `:' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. + "$@" $dashmflag | + sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + tr ' ' ' +' < "$tmpdepfile" | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no + for arg in "$@"; do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix="`echo $object | sed 's/^.*\././'`" + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + sed '1,2d' "$tmpdepfile" | tr ' ' ' +' | \ +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test $1 != '--mode=compile'; do + shift + done + shift + fi + + # Remove `-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E | + sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | + sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o, + # because we must use -o when running libtool. + "$@" || exit $? + IFS=" " + for arg + do + case "$arg" in + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" + echo " " >> "$depfile" + . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/install-sh b/install-sh new file mode 100755 index 0000000..e9de238 --- /dev/null +++ b/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/main.c b/main.c new file mode 100644 index 0000000..02b1eb6 --- /dev/null +++ b/main.c @@ -0,0 +1,935 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + */ +#include "pool.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +#ifdef HAVE_GETOPT_H +#include +#endif + +#include "version.h" + +#define PGPOOLMAXLITSENQUEUELENGTH 10000 +static void daemonize(void); +static int read_pid_file(void); +static void write_pid_file(void); +static pid_t fork_a_child(int unix_fd, int inet_fd); +static int create_unix_domain_socket(void); +static int create_inet_domain_socket(const char *hostname); +static void myexit(int code); + +static RETSIGTYPE exit_handler(int sig); +static RETSIGTYPE reap_handler(int sig); +static RETSIGTYPE failover_handler(int sig); +static RETSIGTYPE health_check_timer_handler(int sig); + +static void usage(void); +static void stop_me(void); +static void switch_me(void); + +static struct sockaddr_un un_addr; /* unix domain socket path */ + +static pid_t *pids; /* child pid table */ + +static int unix_fd; /* unix domain socket fd */ +static int inet_fd; /* inet domain socket fd */ + +static int exiting = 0; /* non 0 if I'm exiting */ +static int switching = 0; /* non 0 if I'm fail overing or degenerating */ +static int degenerated = 0; /* set non 0 if already degerated */ + +static int not_detach = 0; /* non 0 if non detach option (-n) is given */ +int debug = 0; /* non 0 if debug option is given (-d) */ + +static pid_t mypid; /* pgpool parent process id */ + +long int weight_master; /* normalized weight of master (0-RAND_MAX range) */ + +static int stop_sig = SIGTERM; /* stopping signal default value */ +static int switch_over_sig = SIGUSR1; /* switch over signal default value */ + +static int health_check_timer_expired; /* non 0 if health check timer expired */ + +/* +* pgpool main program +*/ +int main(int argc, char **argv) +{ + int opt; + char conf_file[POOLMAXPATHLEN+1]; + int i; + int pid; + + snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); + + while ((opt = getopt(argc, argv, "df:hm:ns:")) != -1) + { + switch (opt) + { + case 'd': /* debug option */ + debug = 1; + break; + + case 'f': /* specify configuration file */ + if (!optarg) + { + usage(); + exit(1); + } + strncpy(conf_file, optarg, sizeof(conf_file)); + break; + + case 'h': + usage(); + exit(0); + break; + + case 'm': /* stop mode */ + if (!optarg) + { + usage(); + exit(1); + } + if (*optarg == 's' || !strcmp("smart", optarg)) + stop_sig = SIGTERM; /* smart shutdown */ + else if (*optarg == 'f' || !strcmp("fast", optarg)) + stop_sig = SIGINT; /* fast shutdown */ + else if (*optarg == 'i' || !strcmp("immediate", optarg)) + stop_sig = SIGQUIT; /* immediate shutdown */ + else + { + usage(); + exit(1); + } + break; + + case 'n': /* no detaching control ttys */ + not_detach = 1; + break; + + case 's': /* switch over request */ + if (!optarg) + { + usage(); + exit(1); + } + if (*optarg == 'm' || !strcmp("master", optarg)) + switch_over_sig = SIGUSR1; /* stopping master */ + else if (*optarg == 's' || !strcmp("secondary", optarg)) + switch_over_sig = SIGUSR2; /* stopping secondary */ + else + { + usage(); + exit(1); + } + break; + + default: + usage(); + exit(1); + } + } + + if (pool_get_config(conf_file)) + { + pool_error("Unable to get configuration. Exiting..."); + mypid = getpid(); + myexit(1); + } + + /* set current PostgreSQL backend */ + pool_config.current_backend_host_name = pool_config.backend_host_name; + pool_config.current_backend_port = pool_config.backend_port; + + /* set load balance weight */ + weight_master = (RAND_MAX) * (pool_config.weight_master / + (pool_config.weight_master + pool_config.weight_secondary)); + pool_debug("weight: %ld", weight_master); + + if (optind == (argc - 1)) + { + if (!strcmp(argv[optind], "stop")) + { + stop_me(); + exit(0); + } + else if (!strcmp(argv[optind], "switch")) + { + switch_me(); + exit(0); + } + } + else if (optind == argc) + { + pid = read_pid_file(); + if (pid > 0) + { + if (kill(pid, 0) == 0) + { + fprintf(stderr, "pid file found. is another pgpool(%d) is running?\n", pid); + exit(1); + } + else + fprintf(stderr, "pid file found but it seems bogus. Trying to start pgpool anyway...\n"); + } + } + else if (optind < argc) + { + usage(); + exit(1); + } + + + /* set signal masks */ + poolinitmask(); + + if (not_detach) + write_pid_file(); + else + daemonize(); + + mypid = getpid(); + + /* set unix domain socket path */ + snprintf(un_addr.sun_path, sizeof(un_addr.sun_path), "%s/.s.PGSQL.%d", + pool_config.socket_dir, + pool_config.port); + + /* set up signal handlers */ + pool_signal(SIGPIPE, SIG_IGN); + + /* create unix domain socket */ + unix_fd = create_unix_domain_socket(); + + /* create inet domain socket if any */ + if (pool_config.listen_addresses[0]) + { + inet_fd = create_inet_domain_socket(pool_config.listen_addresses); + } + + pids = malloc(pool_config.num_init_children * sizeof(pool_config.num_init_children)); + if (pids == NULL) + { + pool_error("failed to allocate pids"); + myexit(1); + } + memset(pids, 0, pool_config.num_init_children * sizeof(pool_config.num_init_children)); + + /* fork the children */ + for (i=0;i 0) + { + int sts; + unsigned int sleep_time; + + pool_log("starting health checking"); + + if (pool_config.health_check_timeout > 0) + { + /* + * set health checker timeout. we want to detect + * commnuication path failure much earlier before + * TCP/IP statck detects it. + */ + pool_signal(SIGALRM, health_check_timer_handler); + alarm(pool_config.health_check_timeout); + } + + /* + * do actual health check. trying to connect to the backend + */ + health_check_timer_expired = 0; + sts = health_check(); + + if (health_check_timer_expired) + { + if (sts == -1) + { + failover_handler(SIGUSR1); /* master down */ + } + else if (sts == -2) + { + failover_handler(SIGUSR2); /* secondary down */ + } + } + + if (pool_config.health_check_timeout > 0) + { + /* seems ok. cancel health check timer */ + pool_signal(SIGALRM, SIG_IGN); + } + + sleep_time = pool_config.health_check_period; + while (sleep_time > 0) + { + sleep_time = sleep(sleep_time); + } + } + else + { + pause(); + } + } + return 0; +} + +static void usage(void) +{ + fprintf(stderr, "pgpool version %s(%s),\n", VERSION, PGPOOLVERSION); + fprintf(stderr, " a generic connection pool/replication/load balance server for PostgreSQL\n\n"); + fprintf(stderr, "usage: pgpool [-f config_file][-n][-d]\n"); + fprintf(stderr, "usage: pgpool [-f config_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop\n"); + fprintf(stderr, "usage: pgpool [-f config_file] [-s {m[aster]|s[econdary]] switch\n"); + fprintf(stderr, "usage: pgpool -h\n"); + fprintf(stderr, " config_file default path: %s/%s\n",DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME); + fprintf(stderr, " -n: don't run in daemon mode. does not detatch control tty\n"); + fprintf(stderr, " -d: debug mode. lots of debug information will be printed\n"); + fprintf(stderr, " stop: stop pgpool\n"); + fprintf(stderr, " switch: send switch over request to pgpool\n"); + fprintf(stderr, " -h: print this help\n"); +} + +/* +* detatch control ttys +*/ +static void daemonize(void) +{ + int i; + pid_t pid; + + pid = fork(); + if (pid == (pid_t) -1) + { + pool_error("fork() failed. reason: %s", strerror(errno)); + exit(1); + return; /* not reached */ + } + else if (pid > 0) + { /* parent */ + exit(0); + } + +#ifdef HAVE_SETSID + if (setsid() < 0) + { + pool_error("setsid() failed. reason:%s", strerror(errno)); + exit(1); + } +#endif + + i = open("/dev/null", O_RDWR); + dup2(i, 0); + dup2(i, 1); + dup2(i, 2); + close(i); + + write_pid_file(); +} + + +/* +* stop myself +*/ +static void stop_me(void) +{ + pid_t pid; + + pid = read_pid_file(); + if (pid < 0) + { + pool_error("could read pid file"); + exit(1); + } + + if (kill(pid, stop_sig) == -1) + { + pool_error("could not stop pid: %d. reason: %s", pid, strerror(errno)); + exit(1); + } + + fprintf(stderr, "stop request sent to pgpool. waiting for termination..."); + + while (kill(pid, 0) == 0) + { + fprintf(stderr, "."); + sleep(1); + } + fprintf(stderr, "done.\n"); +} + +/* +* switch over request +*/ +static void switch_me(void) +{ + pid_t pid; + + pid = read_pid_file(); + + if (pid < 0) + { + pool_error("could read pid file"); + exit(1); + } + + if (kill(pid, switch_over_sig) == -1) + { + pool_error("could not send switch over request to pid: %d. reason: %s", pid, strerror(errno)); + exit(1); + } + + pool_log("switch over request sent"); +} + +/* +* read the pid file +*/ +static int read_pid_file(void) +{ + FILE *fd; + char path[POOLMAXPATHLEN]; + char pidbuf[128]; + + snprintf(path, sizeof(path), "%s/%s", pool_config.logdir, PID_FILE_NAME); + fd = fopen(path, "r"); + if (!fd) + { + return -1; + } + if (fread(pidbuf, 1, sizeof(pidbuf), fd) <= 0) + { + pool_error("could not read pid file as %s. reason: %s", + path, strerror(errno)); + fclose(fd); + return -1; + } + fclose(fd); + return(atoi(pidbuf)); +} + +/* +* write the pid file +*/ +static void write_pid_file(void) +{ + FILE *fd; + char path[POOLMAXPATHLEN]; + char pidbuf[128]; + + snprintf(path, sizeof(path), "%s/%s", pool_config.logdir, PID_FILE_NAME); + fd = fopen(path, "w"); + if (!fd) + { + pool_error("could not open pid file as %s. reason: %s", + path, strerror(errno)); + exit(1); + } + snprintf(pidbuf, sizeof(pidbuf), "%d", (int)getpid()); + fwrite(pidbuf, strlen(pidbuf), 1, fd); + if (fclose(fd)) + { + pool_error("could not write pid file as %s. reason: %s", + path, strerror(errno)); + exit(1); + } +} + +/* +* fork a child +*/ +pid_t fork_a_child(int unix_fd, int inet_fd) +{ + pid_t pid; + + pid = fork(); + + if (pid == 0) + { + /* call child main */ + POOL_SETMASK(&UnBlockSig); + do_child(unix_fd, inet_fd); + } + else if (pid == -1) + { + pool_error("fork() failed. reason: %s", strerror(errno)); + myexit(1); + } + return pid; +} + +/* +* create inet domain socket +*/ +static int create_inet_domain_socket(const char *hostname) +{ + struct sockaddr_in addr; + int fd; + int status; + int one = 1; + int len; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd == -1) + { + pool_error("Failed to create INET domain socket. reason: %s", strerror(errno)); + myexit(1); + } + if ((setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *) &one, + sizeof(one))) == -1) + { + pool_error("setsockopt() failed. reason: %s", strerror(errno)); + myexit(1); + } + + memset((char *) &addr, 0, sizeof(addr)); + ((struct sockaddr *)&addr)->sa_family = AF_INET; + + if (strcmp(hostname, "*")==0) + { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + else + { + struct hostent *hostinfo; + + hostinfo = gethostbyname(hostname); + if (!hostinfo) + { + pool_error("could not resolve host name \"%s\": %s", hostname, hstrerror(h_errno)); + myexit(1); + } + addr.sin_addr = *(struct in_addr *) hostinfo->h_addr; + } + + addr.sin_port = htons(pool_config.port); + len = sizeof(struct sockaddr_in); + status = bind(fd, (struct sockaddr *)&addr, len); + if (status == -1) + { + pool_error("bind() failed. reason: %s", strerror(errno)); + myexit(1); + } + + status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH); + if (status < 0) + { + pool_error("listen() failed. reason: %s", strerror(errno)); + myexit(1); + } + return fd; +} + +/* +* create UNIX domain socket +*/ +static int create_unix_domain_socket(void) +{ + struct sockaddr_un addr; + int fd; + int status; + int len; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + { + pool_error("Failed to create UNIX domain socket. reason: %s", strerror(errno)); + myexit(1); + } + memset((char *) &addr, 0, sizeof(addr)); + ((struct sockaddr *)&addr)->sa_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), un_addr.sun_path); + len = sizeof(struct sockaddr_un); + status = bind(fd, (struct sockaddr *)&addr, len); + if (status == -1) + { + pool_error("bind() failed. reason: %s", strerror(errno)); + myexit(1); + } + + if (chmod(un_addr.sun_path, 0777) == -1) + { + pool_error("chmod() failed. reason: %s", strerror(errno)); + myexit(1); + } + + status = listen(fd, PGPOOLMAXLITSENQUEUELENGTH); + if (status < 0) + { + pool_error("listen() failed. reason: %s", strerror(errno)); + myexit(1); + } + return fd; +} + +static void myexit(int code) +{ + char path[POOLMAXPATHLEN]; + + if (getpid() != mypid) + return; + + unlink(un_addr.sun_path); + snprintf(path, sizeof(path), "%s/%s", pool_config.logdir, PID_FILE_NAME); + unlink(path); + + exit(code); +} + +/* notice backend connection error using SIGUSR1 or SIGUSR2 */ +void notice_backend_error(int master) +{ + pid_t parent = getppid(); + + pool_log("notice_backend_error: master: %d fail over request from pid %d", master, getpid()); + + if (master) + kill(parent, SIGUSR1); + else + kill(parent, SIGUSR2); + + /* avoid race conditon with SIGCHLD */ +#ifdef NOT_USED + sleep(1); +#endif +} + +static RETSIGTYPE exit_handler(int sig) +{ + int i; + + POOL_SETMASK(&AuthBlockSig); + + /* + * this could happend in a child process if a signal has been sent + * before resetting signal handler + */ + if (getpid() != mypid) + { + pool_debug("exit_handler: I am not parent"); + POOL_SETMASK(&UnBlockSig); + exit(0); + } + + if (sig == SIGTERM) + pool_log("received smart shutdown request"); + else if (sig == SIGINT) + pool_log("received fast shutdown request"); + else if (sig == SIGQUIT) + pool_log("received immediate shutdown request"); + else + { + pool_error("exit_handler: unknown signal received %d", sig); + POOL_SETMASK(&UnBlockSig); + return; + } + + exiting = 1; + + for (i = 0; i < pool_config.num_init_children; i++) + { + pid_t pid = pids[i]; + if (pid) + { + kill(pid, sig); + } + } + while (wait(NULL) > 0) + ; + + if (errno != ECHILD) + pool_error("wait() failed. reason:%s", strerror(errno)); + + POOL_SETMASK(&UnBlockSig); + + myexit(0); +} + + +/* + * handle SIGUSR1/SIGUSR2 (backend connection error, fail over request, if possible) + * + * if sig == SIGUSR1, we assume that the master has been down. + * if sig == SIGUSR2, we assume that the secondary has been down. + */ +static RETSIGTYPE failover_handler(int sig) +{ + int i; + int replication = 0; + + POOL_SETMASK(&BlockSig); + + pool_debug("failover_handler called"); + + /* + * this could happen in a child process if a signal has been sent + * before resetting signal handler + */ + if (getpid() != mypid) + { + pool_debug("failover_handler: I am not parent"); + POOL_SETMASK(&UnBlockSig); + return; + } + + /* + * processing SIGTERM, SIGINT or SIGQUIT + */ + if (exiting) + { + POOL_SETMASK(&UnBlockSig); + return; + } + + /* + * processing fail over or switch over + */ + if (switching) + { + POOL_SETMASK(&UnBlockSig); + return; + } + +#ifdef NOT_USED + /* secondary backend exists? */ + if (pool_config.secondary_backend_port == 0) + return; +#endif + + /* + * if not in replication mode/master slave mode, we treat this a restart request. + * otherwise we need to check if we have already failovered. + */ + if (!pool_config.replication_enabled || !pool_config.master_slave_enabled || + strcmp(pool_config.current_backend_host_name, pool_config.secondary_backend_host_name) || + pool_config.current_backend_port != pool_config.secondary_backend_port) + { + switching = 1; + + if (pool_config.replication_enabled) + { + replication = 1; + degenerated = 1; + + if (sig == SIGUSR2) + { + pool_log("starting degeneration. shutdown secondary host %s(%d)", + pool_config.secondary_backend_host_name, + pool_config.secondary_backend_port); + } + else + { + pool_log("starting degeneration. shutdown master host %s(%d)", + pool_config.backend_host_name, + pool_config.backend_port); + } + } + else if (!degenerated && pool_config.secondary_backend_port != 0) + { + pool_log("starting failover from %s(%d) to %s(%d)", + pool_config.current_backend_host_name, + pool_config.current_backend_port, + pool_config.secondary_backend_host_name, + pool_config.secondary_backend_port); + } + else + { + pool_log("restarting pgpool"); + } + + /* kill all children */ + for (i = 0; i < pool_config.num_init_children; i++) + { + pid_t pid = pids[i]; + if (pid) + { + kill(pid, SIGQUIT); + pool_debug("kill %d", pid); + } + } + + while (wait(NULL) > 0) + ; + + if (errno != ECHILD) + pool_error("wait() failed. reason:%s", strerror(errno)); + + if (pool_config.replication_enabled) + { + /* disable replicaton mode */ + pool_config.replication_enabled = 0; + + if (sig == SIGUSR1) + { + pool_config.current_backend_host_name = pool_config.secondary_backend_host_name; + pool_config.current_backend_port = pool_config.secondary_backend_port; + } + } + else if (!degenerated && pool_config.secondary_backend_port != 0) + { + /* fail over to secondary */ + pool_config.current_backend_host_name = pool_config.secondary_backend_host_name; + pool_config.current_backend_port = pool_config.secondary_backend_port; + } + + /* fork the children */ + for (i=0;i 0) + { +#else + while ((pid = wait3(&status, WNOHANG, NULL)) > 0) + { +#endif + + pool_debug("child %d exits with status %d by signal %d", pid, status, WTERMSIG(status)); + + /* look for exiting child's pid */ + for (i=0;i, 1996. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +run=: + +# In the cases where this matters, `missing' is being run in the +# srcdir already. +if test -f configure.ac; then + configure_ac=configure.ac +else + configure_ac=configure.in +fi + +msg="missing on your system" + +case "$1" in +--run) + # Try to run requested program, and just exit if it succeeds. + run= + shift + "$@" && exit 0 + # Exit code 63 means version mismatch. This often happens + # when the user try to use an ancient version of a tool on + # a file that requires a minimum version. In this case we + # we should proceed has if the program had been absent, or + # if --run hadn't been passed. + if test $? = 63; then + run=: + msg="probably too old" + fi + ;; +esac + +# If it does not exist, or fails to run (possibly an outdated version), +# try to emulate it. +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + --run try to run the given command, and emulate it if it fails + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + help2man touch the output file + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + tar try tar, gnutar, gtar, then tar without non-portable flags + yacc create \`y.tab.[ch]', if possible, from existing .[ch] + +Send bug reports to ." + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing $scriptversion (GNU Automake)" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acinclude.m4' or \`${configure_ac}'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`${configure_ac}'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`acconfig.h' or \`${configure_ac}'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` + test -z "$files" && files="config.h" + touch_files= + for f in $files; do + case "$f" in + *:*) touch_files="$touch_files "`echo "$f" | + sed -e 's/^[^:]*://' -e 's/:.*//'`;; + *) touch_files="$touch_files $f.in";; + esac + done + touch $touch_files + ;; + + automake*) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print | + sed 's/\.am$/.in/' | + while read f; do touch "$f"; done + ;; + + autom4te) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is needed, but is $msg. + You might have modified some files without having the + proper tools for further handling them. + You can get \`$1' as part of \`Autoconf' from any GNU + archive site." + + file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'` + test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'` + if test -f "$file"; then + touch $file + else + test -z "$file" || exec >$file + echo "#! /bin/sh" + echo "# Created by GNU Automake missing as a replacement of" + echo "# $ $@" + echo "exit 0" + chmod +x $file + exit 1 + fi + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' $msg. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + help2man) + if test -z "$run" && ($1 --version) > /dev/null 2>&1; then + # We have it, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a dependency of a manual page. You may need the + \`Help2man' package in order for those modifications to take + effect. You can get \`Help2man' from any GNU archive site." + + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'` + fi + if [ -f "$file" ]; then + touch $file + else + test -z "$file" || exec >$file + echo ".ab help2man is required to generate this page" + exit 1 + fi + ;; + + makeinfo) + if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then + # We have makeinfo, but it failed. + exit 1 + fi + + echo 1>&2 "\ +WARNING: \`$1' is $msg. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + tar) + shift + if test -n "$run"; then + echo 1>&2 "ERROR: \`tar' requires --run" + exit 1 + fi + + # We have already tried tar in the generic part. + # Look for gnutar/gtar before invocation to avoid ugly error + # messages. + if (gnutar --version > /dev/null 2>&1); then + gnutar "$@" && exit 0 + fi + if (gtar --version > /dev/null 2>&1); then + gtar "$@" && exit 0 + fi + firstarg="$1" + if shift; then + case "$firstarg" in + *o*) + firstarg=`echo "$firstarg" | sed s/o//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + case "$firstarg" in + *h*) + firstarg=`echo "$firstarg" | sed s/h//` + tar "$firstarg" "$@" && exit 0 + ;; + esac + fi + + echo 1>&2 "\ +WARNING: I can't seem to be able to run \`tar' with the given arguments. + You may want to install GNU tar or Free paxutils, or check the + command line arguments." + exit 1 + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and is $msg. + You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequisites for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-end: "$" +# End: diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 0000000..6b3b5fc --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id$ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/pgpool.conf.sample b/pgpool.conf.sample new file mode 100644 index 0000000..76bb77f --- /dev/null +++ b/pgpool.conf.sample @@ -0,0 +1,102 @@ +# +# pgpool configuration file sample +# $Header$ + +# host name or IP address to listen on: '*' for all, '' for no TCP/IP connections +listen_addresses = 'localhost' + +# port number for pgpool +port = 9999 + +# Unix domain socket path. Debian package default to /var/run/postgresql! +socket_dir = '/tmp' + +# host name where PostgreSQL server is running on. '' means localhost using UNIX +# domain socket +backend_host_name = '' + +# port number PostgreSQL server is running on. +backend_port = 5432 + +# Unix domain socket path for the backend. Debian package default to /var/run/postgresql! +backend_socket_dir = '/tmp' + +# host name where secondary PostgreSQL server is running on. '' means localhost using UNIX +# domain socket +secondary_backend_host_name = '' + +# port number secondary PostgreSQL server is running on. +# 0 means no secondrary PostgreSQL +secondary_backend_port = 0 + +# number of pre-forked child process +num_init_children = 32 + +# numer of connection pool allowed for a child process. +max_pool = 4 + +# if idle for this seconds, child exits. 0 means no timeout. +child_life_time = 300 + +# if idle for this seconds, connection to PostgreSQL closes. 0 means +# no timeout +connection_life_time = 0 + +# logging directory +logdir = '/tmp' + +# replication mode +replication_mode = false + +# set this to true if you want to avoid deadlock situation when +# replication enabled. +# there will be noticable performance degration, however. +# a work around is set this to false and insert /*STRICT*/ comment +# at the beginning of the SQL command. +replication_strict = true + +# when replication_strict is set to false, there will be a chance for +# deadlocks. set this to non 0 (in milli seconds) to detect this +# situation and resolve the deadlock aborting current session. +replication_timeout = 5000 + +# load balancing mode. i.e. all SELECT except in a transaction block +# are load balanced. This is ignored if replication_mode is false. +load_balance_mode = false + +# load balance weight for master and secondary. actual weight is +# calculated by weight_master:weight_secondary. For example both +# +# weight_master = 10 and weight_secondary = 5 +# weight_master = 4 and weight_secondary = 2 +# +# are regarded as master has double the weight comparing with secondary. +# master and secondary have same weight in the default. +weight_master = 0.5 +weight_secondary = 0.5 + +# if there's a data mismatch between master and secondary +# start degenration to stop replication mode +replication_stop_on_mismatch = false + +# semicolon separated list of quries to be issued at the end of session +reset_query_list = 'ABORT; RESET ALL; SET SESSION AUTHORIZATION DEFAULT' + +# if true print time stamp to each log line +print_timestamp = true + +# if true, operate in master/slave mode +master_slave_mode = false + +# if true, cache connection pool +connection_cache = true + +# health check timeout. 0 means no timeout; +health_check_timeout = 20 + +# health check period. 0 means no health check +health_check_period = 0 + +# health check user +health_check_user = 'nobody' + diff --git a/pool.h b/pool.h new file mode 100644 index 0000000..4b82420 --- /dev/null +++ b/pool.h @@ -0,0 +1,315 @@ +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool.h.: master definition header file + * + */ + +#ifndef POOL_H +#define POOL_H + +#include "config.h" +#include "pool_signal.h" +#include +#include + +/* undef this if you have problems with non blocking accept() */ +#define NONE_BLOCK + +#define POOLMAXPATHLEN 8192 + +/* configuration file name */ +#define POOL_CONF_FILE_NAME "pgpool.conf" + +/* pid file directory */ +#define DEFAULT_LOGDIR "/tmp" + +/* Unix domain socket directory */ +#define DEFAULT_SOCKET_DIR "/tmp" + +/* pid file name */ +#define PID_FILE_NAME "pgpool.pid" + +/* strict mode comment in SQL */ +#define STRICT_MODE_STR "/*STRICT*/" +#define STRICT_MODE(s) (strncasecmp((s), STRICT_MODE_STR, strlen(STRICT_MODE_STR)) == 0) + +typedef enum { + POOL_CONTINUE = 0, + POOL_IDLE, + POOL_END, + POOL_ERROR, + POOL_FATAL +} POOL_STATUS; + +/* protocol major version numbers */ +#define PROTO_MAJOR_V2 2 +#define PROTO_MAJOR_V3 3 + +/* + * startup packet definitions (v2) stolen from PostgreSQL + */ +#define SM_DATABASE 64 +#define SM_USER 32 +#define SM_OPTIONS 64 +#define SM_UNUSED 64 +#define SM_TTY 64 + +typedef struct StartupPacket_v2 +{ + int protoVersion; /* Protocol version */ + char database[SM_DATABASE]; /* Database name */ + char user[SM_USER]; /* User name */ + char options[SM_OPTIONS]; /* Optional additional args */ + char unused[SM_UNUSED]; /* Unused */ + char tty[SM_TTY]; /* Tty for debug output */ +} StartupPacket_v2; + +/* startup packet info */ +typedef struct +{ + char *startup_packet; /* raw startup packet without packet length (malloced area) */ + int len; /* raw startup packet length */ + int major; /* protocol major version */ + int minor; /* protocol minor version */ + char *database; /* database name in startup_packet (malloced area) */ + char *user; /* user name in startup_packet (malloced area) */ +} StartupPacket; + +typedef struct CancelPacket +{ + int protoVersion; /* Protocol version */ + int pid; /* bcckend process id */ + int key; /* cancel key */ +} CancelPacket; + +/* + * configuration paramters + */ +typedef struct { + char *listen_addresses; /* hostnames/IP addresses to listen on */ + int port; /* port # to bind */ + char *socket_dir; /* pgpool socket directory */ + char *backend_host_name; /* backend host name */ + int backend_port; /* backend port # */ + char *secondary_backend_host_name; /* secondary backend host name */ + int secondary_backend_port; /* secondary backend port # */ + int num_init_children; /* # of children initially pre-forked */ + int child_life_time; /* if idle for this seconds, child exits */ + int connection_life_time; /* if idle for this seconds, connection closes */ + int max_pool; /* max # of connection pool per child */ + char *logdir; /* logging directory */ + char *backend_socket_dir; /* Unix domain socket directory for the PostgreSQL server */ + int replication_mode; /* replication mode */ + int replication_strict; /* if non 0, wait for completion of the + query sent to master to avoid deadlock */ + double weight_master; /* master weight for load balancing */ + double weight_secondary; /* secondary weight for load balancing */ + /* + * if secondary does not respond in this milli seconds, abort this session. + * this is not compatible with replication_strict = 1. 0 means no timeout. + */ + int replication_timeout; + + int load_balance_mode; /* load balance mode */ + + int replication_stop_on_mismatch; /* if there's a data mismatch between master and secondary + * start degenration to stop replication mode + */ + char **reset_query_list; /* comma separated list of quries to be issued at the end of session */ + + int print_timestamp; /* if non 0 print time stamp to each log line */ + int master_slave_mode; /* if non 0, operate in master/slave mode */ + int connection_cache; /* if non 0, cache connection pool */ + int health_check_timeout; /* health check timeout */ + int health_check_period; /* health check period */ + char *health_check_user; /* PostgreSQL user name for health check */ + + /* followings do not exist in the configuration file */ + char *current_backend_host_name; /* current backend host name */ + int current_backend_port; /* current backend port # */ + int replication_enabled; /* replication mode enabled */ + int master_slave_enabled; /* master/slave mode enabled */ + int num_reset_queries; /* number of queries in reset_query_list */ +} POOL_CONFIG; + +#define MAX_PASSWORD_SIZE 1024 + +typedef struct { + int num; /* number of entries */ + char **names; /* parameter names */ + char **values; /* values */ +} ParamStatus; + +/* + * stream connection structure + */ +typedef struct { + int fd; /* fd for connection */ + FILE *write_fd; /* stream write connection */ + + char *hp; /* pending data buffer head address */ + int po; /* pending data offset */ + int bufsz; /* pending data buffer size */ + int len; /* pending data length */ + + char *sbuf; /* buffer for pool_read_string */ + int sbufsz; /* its size in bytes */ + + char *buf2; /* buffer for pool_read2 */ + int bufsz2; /* its size in bytes */ + + int isbackend; /* this connection is for backend if non 0 */ + int issecondary_backend; /* this connection is for secondary backend if non 0 */ + + char tstate; /* transaction state (V3 only) */ + + /* + * following are used to remember when re-use the authenticated connection + */ + int auth_kind; /* 3: clear text password, 4: crypt password, 5: md5 password */ + int pwd_size; /* password (sent back from frontend) size in host order */ + char password[MAX_PASSWORD_SIZE]; /* password (sent back from frontend) */ + char salt[4]; /* password salt */ + + /* + * following are used to remember current session paramter status. + * re-used connection will need them (V3 only) + */ + ParamStatus params; + + int no_forward; /* if non 0, do not write to frontend */ + +} POOL_CONNECTION; + +/* + * connection pool structure + */ +typedef struct { + StartupPacket *sp; /* startup packet info */ + int pid; /* backend pid */ + int key; /* cancel key */ + POOL_CONNECTION *con; + time_t closetime; /* absolute time in second when the connection closed + * if 0, that means the connection is under use. + */ +} POOL_CONNECTION_POOL_SLOT; + +#define MAX_CONNECTION_SLOTS 2 + +typedef struct { + int num; /* number of slots */ + POOL_CONNECTION_POOL_SLOT *slots[MAX_CONNECTION_SLOTS]; +} POOL_CONNECTION_POOL; + +#define MASTER_CONNECTION(p) ((p)->slots[0]) +#define SECONDARY_CONNECTION(p) ((p)->slots[1]) +#define REPLICATION (pool_config.replication_enabled) +#define MASTER_SLAVE (pool_config.master_slave_enabled) +#define DUAL_MODE (REPLICATION || MASTER_SLAVE) +#define MASTER(p) MASTER_CONNECTION(p)->con +#define SECONDARY(p) SECONDARY_CONNECTION(p)->con +#define MAJOR(p) MASTER_CONNECTION(p)->sp->major +#define TSTATE(p) MASTER(p)->tstate + +#define Max(x, y) ((x) > (y) ? (x) : (y)) +#define Min(x, y) ((x) < (y) ? (x) : (y)) + +/* + * global variables + */ +extern POOL_CONFIG pool_config; /* configuration values */ +extern POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ +extern long int weight_master; /* normalized weight of master (0-RAND_MAX range) */ + +/* + * public functions + */ +extern void pool_error(const char *fmt,...); +extern void pool_debug(const char *fmt,...); +extern void pool_log(const char *fmt,...); +extern int pool_get_config(char *confpath); +extern void do_child(int unix_fd, int inet_fd); +extern int pool_init_cp(void); +extern POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + int connection_reuse); + +extern POOL_CONNECTION *pool_open(int fd); +extern void pool_close(POOL_CONNECTION *cp); +extern int pool_read(POOL_CONNECTION *cp, void *buf, int len); +extern char *pool_read2(POOL_CONNECTION *cp, int len); +extern int pool_write(POOL_CONNECTION *cp, void *buf, int len); +extern int pool_flush(POOL_CONNECTION *cp); +extern int pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len); +extern char *pool_read_string(POOL_CONNECTION *cp, int *len, int line); + +extern int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp); + +extern int pool_init_cp(void); +extern POOL_CONNECTION_POOL *pool_create_cp(void); +extern POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor); +extern void pool_discard_cp(char *user, char *database, int protoMajor); + +extern POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +extern void notice_backend_error(int master); + +extern void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend); +extern RETSIGTYPE pool_backend_timer_handler(int sig); + +extern int connect_inet_domain_socket(int secondary_backend); +extern int connect_unix_domain_socket(int secondary_backend); + +extern int pool_check_fd(POOL_CONNECTION *cp, int notimeout); +extern void pool_enable_timeout(void); +extern void pool_disable_timeout(void); + +extern void pool_send_frontend_exits(POOL_CONNECTION_POOL *backend); + +extern int pool_read_message_length(POOL_CONNECTION_POOL *cp); +extern signed char pool_read_kind(POOL_CONNECTION_POOL *cp); + +extern POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +extern POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); + +extern int pool_init_params(ParamStatus *params); +extern void pool_discard_params(ParamStatus *params); +extern char *pool_find_name(ParamStatus *params, char *name, int *pos); +extern int pool_get_param(ParamStatus *params, int index, char **name, char **value); +extern int pool_add_param(ParamStatus *params, char *name, char *value); +extern void pool_param_debug_print(ParamStatus *params); + +extern void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line); + +extern void pool_free_startup_packet(StartupPacket *sp); +extern int health_check(void); + +#endif /* POOL_H */ diff --git a/pool_auth.c b/pool_auth.c new file mode 100644 index 0000000..7ca499d --- /dev/null +++ b/pool_auth.c @@ -0,0 +1,920 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_auth.c: authenticaton stuff + * +*/ + +#include "pool.h" + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_NETINET_IN_H +#include +#endif +#ifdef HAVE_PARAM_H +#include +#endif +#include +#include + +static POOL_STATUS pool_send_auth_ok(POOL_CONNECTION *frontend, int pid, int key, int protoMajor); +static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); +static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); +static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor); + +/* +* do authentication against backend. if success return 0 otherwise non 0. +*/ +int pool_do_auth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +{ + int status; + signed char kind; + int pid, pid1; + int key, key1; + int protoMajor; + int length; + + protoMajor = MAJOR(cp); + + kind = pool_read_kind(cp); + if (kind < 0) + { + return -1; + } + + /* error response? */ + if (kind == 'E') + { + /* we assume error response at this stage is likely version + * protocol mismatch (v3 frontend vs. v2 backend). So we throw + * a V2 protocol error response in the hope that v3 frontend + * will negotiate again using v2 protocol. + */ + pool_log("pool_do_auth: maybe protocol version mismatch (current version %d)", protoMajor); + ErrorResponse(frontend, cp); + return -1; + } + else if (kind != 'R') + { + pool_error("pool_do_auth: expect \"R\" got %c", kind); + return -1; + } + + /* + * message length (v3 only) */ + if (protoMajor == PROTO_MAJOR_V3 && pool_read_message_length(cp) < 0) + { + return -1; + } + + /* + * read authentication request kind. + * + * 0: authentication ok + * 1: kerberos v4 + * 2: kerberos v5 + * 3: clear text password + * 4: crypt password + * 5: md5 password + * 6: scm credential + * + * in replication mode, we only supports kind = 0, 3. this is because to "salt" + * cannot be replicated among master and secondary. + * in non replication mode, we supports kind = 0, 3, 4, 5 + */ + + status = pool_read(MASTER(cp), &pid, sizeof(pid)); + if (status < 0) + { + pool_error("pool_do_auth: read authentication kind failed"); + return -1; + } + + if (DUAL_MODE) + { + status = pool_read(SECONDARY(cp), &pid1, sizeof(pid1)); + + if (status < 0) + { + pool_error("pool_do_auth: read authentication kind from secondary failed"); + return -1; + } + } + + pid = ntohl(pid); + + /* trust? */ + if (pid == 0) + { + if (protoMajor == PROTO_MAJOR_V3) + { + int msglen; + + pool_write(frontend, "R", 1); + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) + { + return -1; + } + } + MASTER(cp)->auth_kind = 0; + } + + /* clear text password authentication? */ + else if (pid == 3) + { + pool_debug("trying clear text password authentication"); + + pid = do_clear_text_password(MASTER(cp), frontend, 0, protoMajor); + + if (pid >= 0 && DUAL_MODE) + { + pid = do_clear_text_password(SECONDARY(cp), frontend, 0, protoMajor); + } + } + + /* crypt authentication? */ + else if (pid == 4) + { + pool_debug("trying crypt authentication"); + + pid = do_crypt(MASTER(cp), frontend, 0, protoMajor); + + if (pid >= 0 && DUAL_MODE) + { + pid = do_crypt(SECONDARY(cp), frontend, 0, protoMajor); + } + } + + /* md5 authentication? */ + else if (pid == 5) + { + pool_debug("trying md5 authentication"); + + pid = do_md5(MASTER(cp), frontend, 0, protoMajor); + + if (pid >= 0 && DUAL_MODE) + { + pid = do_md5(SECONDARY(cp), frontend, 0, protoMajor); + } + } + + if (pid != 0) + { + pool_error("pool_do_auth: backend does not return authenticaton ok"); + return -1; + } + + /* + * authentication ok. now read pid and secret key from the + * backend + */ + kind = pool_read_kind(cp); + if (kind < 0) + { + return -1; + } + + /* error response? */ + if (kind == 'E') + { + if (protoMajor == PROTO_MAJOR_V2) + ErrorResponse(frontend, cp); + else + SimpleForwardToFrontend(kind, frontend, cp); + return -1; + } + else if (kind != 'K') + { + if (protoMajor == PROTO_MAJOR_V3) + { + /* process parameter status */ + while (kind == 'S') + { + if (ParameterStatus(frontend, cp) != POOL_CONTINUE) + return -1; + + pool_flush(frontend); + + kind = pool_read_kind(cp); + if (kind < 0) + { + pool_error("pool_do_auth: failed to read kind while processing ParamterStatus"); + return -1; + } + } + } + else + { + pool_error("pool_do_auth: expect \"K\" got %c", kind); + return -1; + } + } + + /* + * message length (V3 only) + */ + if (protoMajor == PROTO_MAJOR_V3 && (length = pool_read_message_length(cp)) != 12) + { + pool_error("pool_do_auth: invalid messages length(%d) for BackendKeyData", length); + return -1; + } + + /* + * OK, read pid and secret key + */ + + /* pid */ + pool_read(MASTER(cp), &pid, sizeof(pid)); + MASTER_CONNECTION(cp)->pid = pid; + + /* key */ + pool_read(MASTER(cp), &key, sizeof(key)); + MASTER_CONNECTION(cp)->key = key; + + if (DUAL_MODE) + { + pool_read(SECONDARY(cp), &pid1, sizeof(pid1)); + SECONDARY_CONNECTION(cp)->pid = pid; + + /* key */ + pool_read(SECONDARY(cp), &key1, sizeof(key1)); + SECONDARY_CONNECTION(cp)->key = key; + } + + return (pool_send_auth_ok(frontend, pid, key, protoMajor)); +} + +/* +* do re-authentication for reused connection. if success return 0 otherwise non 0. +*/ +int pool_do_reauth(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *cp) +{ + int status; + int protoMajor; + + protoMajor = MAJOR(cp); + + switch(MASTER(cp)->auth_kind) + { + case 0: + /* trust */ + status = 0; + break; + + case 3: + /* clear text password */ + status = do_clear_text_password(MASTER(cp), frontend, 1, protoMajor); + break; + + case 4: + /* crypt password */ + status = do_crypt(MASTER(cp), frontend, 1, protoMajor); + break; + + case 5: + /* md5 password */ + status = do_md5(MASTER(cp), frontend, 1, protoMajor); + break; + + default: + pool_error("pool_do_reauth: unknown authentication request code %d", + MASTER(cp)->auth_kind); + return -1; + } + + if (status == 0) + { + if (protoMajor == PROTO_MAJOR_V3) + { + int msglen; + + pool_write(frontend, "R", 1); + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) + { + return -1; + } + } + } + else + { + pool_debug("pool_do_reauth: authentication failed"); + return -1; + } + + return (pool_send_auth_ok(frontend, MASTER_CONNECTION(cp)->pid, MASTER_CONNECTION(cp)->key, protoMajor) != POOL_CONTINUE); +} + +/* +* send authentication ok to frontend. if success return 0 otherwise non 0. +*/ +static POOL_STATUS pool_send_auth_ok(POOL_CONNECTION *frontend, int pid, int key, int protoMajor) +{ + char kind; + int len; + + if (protoMajor == PROTO_MAJOR_V2) + { + /* return "Authentication OK" to the frontend */ + kind = 'R'; + pool_write(frontend, &kind, 1); + len = htonl(0); + if (pool_write_and_flush(frontend, &len, sizeof(len)) < 0) + { + return -1; + } + } + + /* send backend key data */ + kind = 'K'; + pool_write(frontend, &kind, 1); + if (protoMajor == PROTO_MAJOR_V3) + { + len = htonl(12); + pool_write(frontend, &len, sizeof(len)); + } + pool_write(frontend, &pid, sizeof(pid)); + if (pool_write_and_flush(frontend, &key, sizeof(key)) < 0) + { + return -1; + } + + return 0; +} + +/* + * perform clear text password authetication + */ +static int do_clear_text_password(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +{ + static int size; + static char password[MAX_PASSWORD_SIZE]; + char response; + int kind; + int len; + + /* master? */ + if (!backend->issecondary_backend) + { + pool_write(frontend, "R", 1); /* authenticaton */ + if (protoMajor == PROTO_MAJOR_V3) + { + len = htonl(8); + pool_write(frontend, &len, sizeof(len)); + } + kind = htonl(3); /* clear text password authentication */ + pool_write_and_flush(frontend, &kind, sizeof(kind)); /* indicating clear text password authentication */ + + /* read password packet */ + if (protoMajor == PROTO_MAJOR_V2) + { + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_clear_text_password: failed to read password packet size"); + return -1; + } + } + else + { + char k; + + if (pool_read(frontend, &k, sizeof(k))) + { + pool_error("do_clear_text_password: failed to read password packet \"p\""); + return -1; + } + if (k != 'p') + { + pool_error("do_clear_text_password: password packet does not start with \"p\""); + return -1; + } + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_clear_text_password: failed to read password packet size"); + return -1; + } + } + + if ((ntohl(size) - 4) > sizeof(password)) + { + pool_error("do_clear_text_password: password is too long (size: %d)", ntohl(size) - 4); + return -1; + } + + if (pool_read(frontend, password, ntohl(size) - 4)) + { + pool_error("do_clear_text_password: failed to read password (size: %d)", ntohl(size) - 4); + return -1; + } + } + + /* connection reusing? */ + if (reauth) + { + if ((ntohl(size) - 4) != backend->pwd_size) + { + pool_debug("do_clear_text_password; password size does not match in re-authetication"); + return -1; + } + + if (memcmp(password, backend->password, backend->pwd_size) != 0) + { + pool_debug("do_clear_text_password; password does not match in re-authetication"); + return -1; + } + + return 0; + } + + /* send password packet to backend */ + if (protoMajor == PROTO_MAJOR_V3) + pool_write(backend, "p", 1); + pool_write(backend, &size, sizeof(size)); + pool_write_and_flush(backend, password, ntohl(size) -4); + if (pool_read(backend, &response, sizeof(response))) + { + pool_error("do_clear_text_password: failed to read authentication response"); + return -1; + } + + if (response != 'R') + { + pool_debug("do_clear_text_password: backend does not return R while processing clear text password authentication"); + return -1; + } + + if (protoMajor == PROTO_MAJOR_V3) + { + if (pool_read(backend, &len, sizeof(len))) + { + pool_error("do_clear_text_password: failed to read authentication packet size"); + return -1; + } + + if (ntohl(len) != 8) + { + pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len)); + return -1; + } + } + + /* expect to read "Authentication OK" response. kind should be 0... */ + if (pool_read(backend, &kind, sizeof(kind))) + { + pool_debug("do_clear_text_password: failed to read Authentication OK response"); + return -1; + } + + /* if authenticated, save info */ + if (!reauth && kind == 0) + { + if (!backend->issecondary_backend && protoMajor == PROTO_MAJOR_V3) + { + int msglen; + + pool_write(frontend, "R", 1); + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) + { + return -1; + } + } + + backend->auth_kind = 3; + backend->pwd_size = ntohl(size) - 4; + memcpy(backend->password, password, backend->pwd_size); + } + return kind; +} + +/* + * perform crypt authetication + */ +static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +{ + char salt[2]; + static int size; + static char password[MAX_PASSWORD_SIZE]; + char response; + int kind; + int len; + + if (!reauth) + { + /* read salt */ + if (pool_read(backend, salt, sizeof(salt))) + { + pool_error("do_crypt: failed to read salt"); + return -1; + } + } + else + { + memcpy(salt, backend->salt, sizeof(salt)); + } + + /* master? */ + if (!backend->issecondary_backend) + { + pool_write(frontend, "R", 1); /* authenticaton */ + if (protoMajor == PROTO_MAJOR_V3) + { + len = htonl(10); + pool_write(frontend, &len, sizeof(len)); + } + kind = htonl(4); /* crypt authentication */ + pool_write(frontend, &kind, sizeof(kind)); /* indicating crypt authentication */ + pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ + + /* read password packet */ + if (protoMajor == PROTO_MAJOR_V2) + { + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_crypt: failed to read password packet size"); + return -1; + } + } + else + { + char k; + + if (pool_read(frontend, &k, sizeof(k))) + { + pool_error("do_crypt_password: failed to read password packet \"p\""); + return -1; + } + if (k != 'p') + { + pool_error("do_crypt_password: password packet does not start with \"p\""); + return -1; + } + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_crypt_password: failed to read password packet size"); + return -1; + } + } + + if ((ntohl(size) - 4) > sizeof(password)) + { + pool_error("do_crypt: password is too long(size: %d)", ntohl(size) - 4); + return -1; + } + + if (pool_read(frontend, password, ntohl(size) - 4)) + { + pool_error("do_crypt: failed to read password (size: %d)", ntohl(size) - 4); + return -1; + } + } + + /* connection reusing? */ + if (reauth) + { + pool_debug("size: %d saved_size: %d", (ntohl(size) - 4), backend->pwd_size); + if ((ntohl(size) - 4) != backend->pwd_size) + { + pool_debug("do_crypt: password size does not match in re-authetication"); + return -1; + } + + if (memcmp(password, backend->password, backend->pwd_size) != 0) + { + pool_debug("do_crypt: password does not match in re-authetication"); + return -1; + } + + return 0; + } + + /* send password packet to backend */ + if (protoMajor == PROTO_MAJOR_V3) + pool_write(backend, "p", 1); + pool_write(backend, &size, sizeof(size)); + pool_write_and_flush(backend, password, ntohl(size) -4); + if (pool_read(backend, &response, sizeof(response))) + { + pool_error("do_crypt: failed to read authentication response"); + return -1; + } + + if (response != 'R') + { + pool_debug("do_crypt: backend does not return R while processing crypt authentication(%02x) secondary: %d", response, backend->issecondary_backend); + return -1; + } + + if (protoMajor == PROTO_MAJOR_V3) + { + if (pool_read(backend, &len, sizeof(len))) + { + pool_error("do_clear_text_password: failed to read authentication packet size"); + return -1; + } + + if (ntohl(len) != 8) + { + pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len)); + return -1; + } + } + + /* expect to read "Authentication OK" response. kind should be 0... */ + if (pool_read(backend, &kind, sizeof(kind))) + { + pool_debug("do_crypt: failed to read Authentication OK response"); + return -1; + } + + /* if authenticated, save info */ + if (!reauth && kind == 0) + { + if (protoMajor == PROTO_MAJOR_V3) + { + int msglen; + + pool_write(frontend, "R", 1); + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) + { + return -1; + } + } + backend->auth_kind = 4; + backend->pwd_size = ntohl(size) - 4; + memcpy(backend->password, password, backend->pwd_size); + memcpy(backend->salt, salt, sizeof(salt)); + } + return kind; +} + +/* + * perform MD5 authetication + */ +static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor) +{ + char salt[4]; + static int size; + static char password[MAX_PASSWORD_SIZE]; + char response; + int kind; + int len; + + if (!reauth) + { + /* read salt */ + if (pool_read(backend, salt, sizeof(salt))) + { + pool_error("do_md5: failed to read salt"); + return -1; + } + pool_debug("master: %d salt: %hhx%hhx%hhx%hhx", !backend->issecondary_backend, + salt[0], salt[1], salt[2], salt[3]); + } + else + { + memcpy(salt, backend->salt, sizeof(salt)); + } + + /* master? */ + if (!backend->issecondary_backend) + { + pool_write(frontend, "R", 1); /* authenticaton */ + if (protoMajor == PROTO_MAJOR_V3) + { + len = htonl(12); + pool_write(frontend, &len, sizeof(len)); + } + kind = htonl(5); + pool_write(frontend, &kind, sizeof(kind)); /* indicating MD5 */ + pool_write_and_flush(frontend, salt, sizeof(salt)); /* salt */ + + /* read password packet */ + if (protoMajor == PROTO_MAJOR_V2) + { + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_md5: failed to read password packet size"); + return -1; + } + } + else + { + char k; + + if (pool_read(frontend, &k, sizeof(k))) + { + pool_error("do_md5_password: failed to read password packet \"p\""); + return -1; + } + if (k != 'p') + { + pool_error("do_md5_password: password packet does not start with \"p\""); + return -1; + } + if (pool_read(frontend, &size, sizeof(size))) + { + pool_error("do_md5_password: failed to read password packet size"); + return -1; + } + } + + if ((ntohl(size) - 4) > sizeof(password)) + { + pool_error("do_md5: password is too long(size: %d)", ntohl(size) - 4); + return -1; + } + + if (pool_read(frontend, password, ntohl(size) - 4)) + { + pool_error("do_md5: failed to read password (size: %d)", ntohl(size) - 4); + return -1; + } + } + + /* connection reusing? */ + if (reauth) + { + if ((ntohl(size) - 4) != backend->pwd_size) + { + pool_debug("do_md5; password size does not match in re-authetication"); + return -1; + } + + if (memcmp(password, backend->password, backend->pwd_size) != 0) + { + pool_debug("do_md5; password does not match in re-authetication"); + return -1; + } + + return 0; + } + + /* send password packet to backend */ + if (protoMajor == PROTO_MAJOR_V3) + pool_write(backend, "p", 1); + pool_write(backend, &size, sizeof(size)); + pool_write_and_flush(backend, password, ntohl(size) -4); + if (pool_read(backend, &response, sizeof(response))) + { + pool_error("do_md5: failed to read authentication response"); + return -1; + } + + if (response != 'R') + { + pool_debug("do_md5: backend does not return R while processing MD5 authentication %c", response); + return -1; + } + + if (protoMajor == PROTO_MAJOR_V3) + { + if (pool_read(backend, &len, sizeof(len))) + { + pool_error("do_md5: failed to read authentication packet size"); + return -1; + } + + if (ntohl(len) != 8) + { + pool_error("do_clear_text_password: incorrect authentication packet size (%d)", ntohl(len)); + return -1; + } + } + + /* expect to read "Authentication OK" response. kind should be 0... */ + if (pool_read(backend, &kind, sizeof(kind))) + { + pool_debug("do_md5: failed to read Authentication OK response"); + return -1; + } + + /* if authenticated, save info */ + if (!reauth && kind == 0) + { + if (protoMajor == PROTO_MAJOR_V3) + { + int msglen; + + pool_write(frontend, "R", 1); + msglen = htonl(8); + pool_write(frontend, &msglen, sizeof(msglen)); + msglen = htonl(0); + if (pool_write_and_flush(frontend, &msglen, sizeof(msglen)) < 0) + { + return -1; + } + } + backend->auth_kind = 5; + backend->pwd_size = ntohl(size) - 4; + memcpy(backend->password, password, backend->pwd_size); + memcpy(backend->salt, salt, sizeof(salt)); + } + return kind; +} + +/* + * read message length (V3 only) + */ +int pool_read_message_length(POOL_CONNECTION_POOL *cp) +{ + int status; + int length, length1; + + status = pool_read(MASTER(cp), &length, sizeof(length)); + if (status < 0) + { + pool_error("read_message_length: error while reading message length"); + return -1; + } + length = ntohl(length); + + pool_debug("read_message_length: lenghth: %d", length); + + if (DUAL_MODE) + { + status = pool_read(SECONDARY(cp), &length1, sizeof(length1)); + if (status < 0) + { + pool_error("read_message_length: error while reading message length from secondary backend"); + return -1; + } + length1 = ntohl(length1); + + if (length != length1) + { + pool_error("read_message_length: length does not match between backends master(%d) secondary(%d)", + length, length1); + return -1; + } + } + + if (length < 0) + { + pool_error("read_message_length: invalid message length (%d)", length); + return -1; + } + + return length; +} + +signed char pool_read_kind(POOL_CONNECTION_POOL *cp) +{ + int status; + char kind, kind1; + + status = pool_read(MASTER(cp), &kind, sizeof(kind)); + if (status < 0) + { + pool_error("read_message_kind: error while reading message kind"); + return -1; + } + + if (DUAL_MODE) + { + status = pool_read(SECONDARY(cp), &kind1, sizeof(kind1)); + if (status < 0) + { + pool_error("read_message_kind: error while reading message kind from secondary backend"); + return -1; + } + + if (kind != kind1) + { + pool_error("read_message_kind: kind does not match between backends master(%d) secondary(%d)", + kind, kind1); + return -1; + } + } + + return kind; +} diff --git a/pool_config.c b/pool_config.c new file mode 100644 index 0000000..51ef731 --- /dev/null +++ b/pool_config.c @@ -0,0 +1,2175 @@ +/* A lexical scanner generated by flex */ + +/* Scanner skeleton version: + * $Header$ + */ + +#define FLEX_SCANNER +#define YY_FLEX_MAJOR_VERSION 2 +#define YY_FLEX_MINOR_VERSION 5 + +#include +#include + + +/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */ +#ifdef c_plusplus +#ifndef __cplusplus +#define __cplusplus +#endif +#endif + + +#ifdef __cplusplus + +#include + +/* Use prototypes in function declarations. */ +#define YY_USE_PROTOS + +/* The "const" storage-class-modifier is valid. */ +#define YY_USE_CONST + +#else /* ! __cplusplus */ + +#if __STDC__ + +#define YY_USE_PROTOS +#define YY_USE_CONST + +#endif /* __STDC__ */ +#endif /* ! __cplusplus */ + +#ifdef __TURBOC__ + #pragma warn -rch + #pragma warn -use +#include +#include +#define YY_USE_CONST +#define YY_USE_PROTOS +#endif + +#ifdef YY_USE_CONST +#define yyconst const +#else +#define yyconst +#endif + + +#ifdef YY_USE_PROTOS +#define YY_PROTO(proto) proto +#else +#define YY_PROTO(proto) () +#endif + +/* Returned upon end-of-file. */ +#define YY_NULL 0 + +/* Promotes a possibly negative, possibly signed char to an unsigned + * integer for use as an array index. If the signed char is negative, + * we want to instead treat it as an 8-bit unsigned char, hence the + * double cast. + */ +#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) + +/* Enter a start condition. This macro really ought to take a parameter, + * but we do it the disgusting crufty way forced on us by the ()-less + * definition of BEGIN. + */ +#define BEGIN yy_start = 1 + 2 * + +/* Translate the current start state into a value that can be later handed + * to BEGIN to return to the state. The YYSTATE alias is for lex + * compatibility. + */ +#define YY_START ((yy_start - 1) / 2) +#define YYSTATE YY_START + +/* Action number for EOF rule of a given start state. */ +#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) + +/* Special action meaning "start processing a new file". */ +#define YY_NEW_FILE yyrestart( yyin ) + +#define YY_END_OF_BUFFER_CHAR 0 + +/* Size of default input buffer. */ +#define YY_BUF_SIZE 16384 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern int yyleng; +extern FILE *yyin, *yyout; + +#define EOB_ACT_CONTINUE_SCAN 0 +#define EOB_ACT_END_OF_FILE 1 +#define EOB_ACT_LAST_MATCH 2 + +/* The funky do-while in the following #define is used to turn the definition + * int a single C statement (which needs a semi-colon terminator). This + * avoids problems with code like: + * + * if ( condition_holds ) + * yyless( 5 ); + * else + * do_something_else(); + * + * Prior to using the do-while the compiler would get upset at the + * "else" because it interpreted the "if" statement as being all + * done when it reached the ';' after the yyless() call. + */ + +/* Return all but the first 'n' matched characters back to the input stream. */ + +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + *yy_cp = yy_hold_char; \ + YY_RESTORE_YY_MORE_OFFSET \ + yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \ + YY_DO_BEFORE_ACTION; /* set up yytext again */ \ + } \ + while ( 0 ) + +#define unput(c) yyunput( c, yytext_ptr ) + +/* The following is because we cannot portably get our hands on size_t + * (without autoconf's help, which isn't available because we want + * flex-generated scanners to compile on their own). + */ +typedef unsigned int yy_size_t; + + +struct yy_buffer_state + { + FILE *yy_input_file; + + char *yy_ch_buf; /* input buffer */ + char *yy_buf_pos; /* current position in input buffer */ + + /* Size of input buffer in bytes, not including room for EOB + * characters. + */ + yy_size_t yy_buf_size; + + /* Number of characters read into yy_ch_buf, not including EOB + * characters. + */ + int yy_n_chars; + + /* Whether we "own" the buffer - i.e., we know we created it, + * and can realloc() it to grow it, and should free() it to + * delete it. + */ + int yy_is_our_buffer; + + /* Whether this is an "interactive" input source; if so, and + * if we're using stdio for input, then we want to use getc() + * instead of fread(), to make sure we stop fetching input after + * each newline. + */ + int yy_is_interactive; + + /* Whether we're considered to be at the beginning of a line. + * If so, '^' rules will be active on the next match, otherwise + * not. + */ + int yy_at_bol; + + /* Whether to try to fill the input buffer when we reach the + * end of it. + */ + int yy_fill_buffer; + + int yy_buffer_status; +#define YY_BUFFER_NEW 0 +#define YY_BUFFER_NORMAL 1 + /* When an EOF's been seen but there's still some text to process + * then we mark the buffer as YY_EOF_PENDING, to indicate that we + * shouldn't try reading from the input source any more. We might + * still have a bunch of tokens to match, though, because of + * possible backing-up. + * + * When we actually see the EOF, we change the status to "new" + * (via yyrestart()), so that the user can continue scanning by + * just pointing yyin at a new input file. + */ +#define YY_BUFFER_EOF_PENDING 2 + }; + +static YY_BUFFER_STATE yy_current_buffer = 0; + +/* We provide macros for accessing buffer states in case in the + * future we want to put the buffer states in a more general + * "scanner state". + */ +#define YY_CURRENT_BUFFER yy_current_buffer + + +/* yy_hold_char holds the character lost when yytext is formed. */ +static char yy_hold_char; + +static int yy_n_chars; /* number of characters read into yy_ch_buf */ + + +int yyleng; + +/* Points to current character in buffer. */ +static char *yy_c_buf_p = (char *) 0; +static int yy_init = 1; /* whether we need to initialize */ +static int yy_start = 0; /* start state number */ + +/* Flag which is used to allow yywrap()'s to do buffer switches + * instead of setting up a fresh yyin. A bit of a hack ... + */ +static int yy_did_buffer_switch_on_eof; + +void yyrestart YY_PROTO(( FILE *input_file )); + +void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer )); +void yy_load_buffer_state YY_PROTO(( void )); +YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size )); +void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b )); +void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file )); +void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b )); +#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer ) + +YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size )); +YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str )); +YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len )); + +static void *yy_flex_alloc YY_PROTO(( yy_size_t )); +static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t )); +static void yy_flex_free YY_PROTO(( void * )); + +#define yy_new_buffer yy_create_buffer + +#define yy_set_interactive(is_interactive) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_is_interactive = is_interactive; \ + } + +#define yy_set_bol(at_bol) \ + { \ + if ( ! yy_current_buffer ) \ + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \ + yy_current_buffer->yy_at_bol = at_bol; \ + } + +#define YY_AT_BOL() (yy_current_buffer->yy_at_bol) + + +#define yywrap() 1 +#define YY_SKIP_YYWRAP +typedef unsigned char YY_CHAR; +FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; +typedef int yy_state_type; +extern char *yytext; +#define yytext_ptr yytext + +static yy_state_type yy_get_previous_state YY_PROTO(( void )); +static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state )); +static int yy_get_next_buffer YY_PROTO(( void )); +static void yy_fatal_error YY_PROTO(( yyconst char msg[] )); + +/* Done after the current pattern has been matched and before the + * corresponding action - sets up yytext. + */ +#define YY_DO_BEFORE_ACTION \ + yytext_ptr = yy_bp; \ + yyleng = (int) (yy_cp - yy_bp); \ + yy_hold_char = *yy_cp; \ + *yy_cp = '\0'; \ + yy_c_buf_p = yy_cp; + +#define YY_NUM_RULES 11 +#define YY_END_OF_BUFFER 12 +static yyconst short int yy_accept[38] = + { 0, + 0, 0, 12, 10, 2, 1, 10, 10, 10, 8, + 7, 7, 9, 4, 2, 0, 3, 0, 5, 0, + 8, 7, 7, 8, 0, 0, 6, 4, 4, 0, + 5, 0, 0, 8, 7, 6, 0 + } ; + +static yyconst int yy_ec[256] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 1, 1, 4, 1, 1, 1, 5, 1, + 1, 1, 6, 1, 7, 8, 9, 10, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 9, 1, 1, + 12, 1, 1, 1, 13, 13, 13, 13, 14, 13, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 1, 16, 1, 1, 17, 1, 13, 13, 13, 13, + + 14, 13, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 18, + 15, 15, 1, 1, 1, 1, 1, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15 + } ; + +static yyconst int yy_meta[19] = + { 0, + 1, 1, 2, 1, 1, 1, 3, 3, 3, 4, + 4, 1, 5, 4, 3, 1, 3, 3 + } ; + +static yyconst short int yy_base[45] = + { 0, + 0, 0, 61, 86, 58, 86, 55, 14, 23, 43, + 10, 46, 86, 28, 47, 40, 86, 16, 86, 22, + 28, 0, 0, 0, 40, 0, 24, 45, 0, 24, + 39, 43, 12, 14, 0, 22, 86, 62, 67, 22, + 70, 75, 77, 80 + } ; + +static yyconst short int yy_def[45] = + { 0, + 37, 1, 37, 37, 37, 37, 38, 39, 37, 40, + 9, 9, 37, 41, 37, 38, 37, 39, 37, 42, + 40, 11, 12, 21, 37, 43, 44, 41, 28, 39, + 39, 42, 37, 37, 43, 44, 0, 37, 37, 37, + 37, 37, 37, 37 + } ; + +static yyconst short int yy_nxt[105] = + { 0, + 4, 5, 6, 7, 8, 9, 9, 10, 4, 11, + 12, 13, 14, 14, 14, 4, 14, 14, 19, 23, + 19, 34, 34, 34, 34, 24, 31, 26, 19, 20, + 21, 20, 22, 23, 27, 27, 27, 32, 36, 20, + 36, 25, 17, 19, 29, 33, 33, 31, 15, 34, + 34, 27, 27, 27, 20, 23, 25, 17, 32, 15, + 37, 29, 16, 16, 16, 16, 16, 18, 37, 18, + 18, 18, 28, 28, 28, 30, 37, 30, 30, 30, + 35, 35, 27, 27, 27, 3, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + + 37, 37, 37, 37 + } ; + +static yyconst short int yy_chk[105] = + { 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 8, 11, + 18, 33, 33, 34, 34, 40, 20, 11, 30, 8, + 9, 18, 9, 9, 14, 14, 14, 20, 36, 30, + 27, 21, 16, 31, 14, 25, 25, 32, 15, 25, + 25, 28, 28, 28, 31, 12, 10, 7, 32, 5, + 3, 28, 38, 38, 38, 38, 38, 39, 0, 39, + 39, 39, 41, 41, 41, 42, 0, 42, 42, 42, + 43, 43, 44, 44, 44, 37, 37, 37, 37, 37, + 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, + + 37, 37, 37, 37 + } ; + +static yy_state_type yy_last_accepting_state; +static char *yy_last_accepting_cpos; + +/* The intent behind this definition is that it'll catch + * any uses of REJECT which flex missed. + */ +#define REJECT reject_used_but_not_detected +#define yymore() yymore_used_but_not_detected +#define YY_MORE_ADJ 0 +#define YY_RESTORE_YY_MORE_OFFSET +char *yytext; +#line 1 "pool_config.l" +#define INITIAL 0 +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_config.l: read configuration file + * + */ +#line 27 "pool_config.l" + +#include "pool.h" + +#include +#include + +/* to shut off compiler warnings */ +int yylex(void); + +POOL_CONFIG pool_config; /* configuration values */ +static unsigned Lineno; + +typedef enum { + POOL_KEY = 1, + POOL_INTEGER, + POOL_REAL, + POOL_STRING, + POOL_UNQUOTED_STRING, + POOL_EQUALS, + POOL_EOL, + POOL_PARSE_ERROR +} POOL_TOKEN; + +static char *extract_string(char *value, POOL_TOKEN token); +static char **extract_string_tokens(char *str, char *delim, int *n); + +#define YY_NEVER_INTERACTIVE 1 +#define YY_NO_UNPUT 1 +#line 453 "pool_config.c" + +/* Macros after this point can all be overridden by user definitions in + * section 1. + */ + +#ifndef YY_SKIP_YYWRAP +#ifdef __cplusplus +extern "C" int yywrap YY_PROTO(( void )); +#else +extern int yywrap YY_PROTO(( void )); +#endif +#endif + +#ifndef YY_NO_UNPUT +static void yyunput YY_PROTO(( int c, char *buf_ptr )); +#endif + +#ifndef yytext_ptr +static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int )); +#endif + +#ifdef YY_NEED_STRLEN +static int yy_flex_strlen YY_PROTO(( yyconst char * )); +#endif + +#ifndef YY_NO_INPUT +#ifdef __cplusplus +static int yyinput YY_PROTO(( void )); +#else +static int input YY_PROTO(( void )); +#endif +#endif + +#if YY_STACK_USED +static int yy_start_stack_ptr = 0; +static int yy_start_stack_depth = 0; +static int *yy_start_stack = 0; +#ifndef YY_NO_PUSH_STATE +static void yy_push_state YY_PROTO(( int new_state )); +#endif +#ifndef YY_NO_POP_STATE +static void yy_pop_state YY_PROTO(( void )); +#endif +#ifndef YY_NO_TOP_STATE +static int yy_top_state YY_PROTO(( void )); +#endif + +#else +#define YY_NO_PUSH_STATE 1 +#define YY_NO_POP_STATE 1 +#define YY_NO_TOP_STATE 1 +#endif + +#ifdef YY_MALLOC_DECL +YY_MALLOC_DECL +#else +#if __STDC__ +#ifndef __cplusplus +#include +#endif +#else +/* Just try to get by without declaring the routines. This will fail + * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int) + * or sizeof(void*) != sizeof(int). + */ +#endif +#endif + +/* Amount of stuff to slurp up with each read. */ +#ifndef YY_READ_BUF_SIZE +#define YY_READ_BUF_SIZE 8192 +#endif + +/* Copy whatever the last rule matched to the standard output. */ + +#ifndef ECHO +/* This used to be an fputs(), but since the string might contain NUL's, + * we now use fwrite(). + */ +#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) +#endif + +/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, + * is returned in "result". + */ +#ifndef YY_INPUT +#define YY_INPUT(buf,result,max_size) \ + if ( yy_current_buffer->yy_is_interactive ) \ + { \ + int c = '*', n; \ + for ( n = 0; n < max_size && \ + (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ + buf[n] = (char) c; \ + if ( c == '\n' ) \ + buf[n++] = (char) c; \ + if ( c == EOF && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); \ + result = n; \ + } \ + else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \ + && ferror( yyin ) ) \ + YY_FATAL_ERROR( "input in flex scanner failed" ); +#endif + +/* No semi-colon after return; correct usage is to write "yyterminate();" - + * we don't want an extra ';' after the "return" because that will cause + * some compilers to complain about unreachable statements. + */ +#ifndef yyterminate +#define yyterminate() return YY_NULL +#endif + +/* Number of entries by which start-condition stack grows. */ +#ifndef YY_START_STACK_INCR +#define YY_START_STACK_INCR 25 +#endif + +/* Report a fatal error. */ +#ifndef YY_FATAL_ERROR +#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) +#endif + +/* Default declaration of generated scanner - a define so the user can + * easily add parameters. + */ +#ifndef YY_DECL +#define YY_DECL int yylex YY_PROTO(( void )) +#endif + +/* Code executed at the beginning of each rule, after yytext and yyleng + * have been set up. + */ +#ifndef YY_USER_ACTION +#define YY_USER_ACTION +#endif + +/* Code executed at the end of each rule. */ +#ifndef YY_BREAK +#define YY_BREAK break; +#endif + +#define YY_RULE_SETUP \ + YY_USER_ACTION + +YY_DECL + { + register yy_state_type yy_current_state; + register char *yy_cp = NULL, *yy_bp = NULL; + register int yy_act; + +#line 77 "pool_config.l" + + +#line 607 "pool_config.c" + + if ( yy_init ) + { + yy_init = 0; + +#ifdef YY_USER_INIT + YY_USER_INIT; +#endif + + if ( ! yy_start ) + yy_start = 1; /* first start state */ + + if ( ! yyin ) + yyin = stdin; + + if ( ! yyout ) + yyout = stdout; + + if ( ! yy_current_buffer ) + yy_current_buffer = + yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_load_buffer_state(); + } + + while ( 1 ) /* loops until end-of-file is reached */ + { + yy_cp = yy_c_buf_p; + + /* Support of yytext. */ + *yy_cp = yy_hold_char; + + /* yy_bp points to the position in yy_ch_buf of the start of + * the current run. + */ + yy_bp = yy_cp; + + yy_current_state = yy_start; +yy_match: + do + { + register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 38 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + ++yy_cp; + } + while ( yy_base[yy_current_state] != 86 ); + +yy_find_action: + yy_act = yy_accept[yy_current_state]; + if ( yy_act == 0 ) + { /* have to back up */ + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + yy_act = yy_accept[yy_current_state]; + } + + YY_DO_BEFORE_ACTION; + + +do_action: /* This label is used only to access EOF actions. */ + + + switch ( yy_act ) + { /* beginning of action switch */ + case 0: /* must back up */ + /* undo the effects of YY_DO_BEFORE_ACTION */ + *yy_cp = yy_hold_char; + yy_cp = yy_last_accepting_cpos; + yy_current_state = yy_last_accepting_state; + goto yy_find_action; + +case 1: +YY_RULE_SETUP +#line 79 "pool_config.l" +Lineno++; return POOL_EOL; + YY_BREAK +case 2: +YY_RULE_SETUP +#line 80 "pool_config.l" +/* eat whitespace */ + YY_BREAK +case 3: +*yy_cp = yy_hold_char; /* undo effects of setting up yytext */ +yy_c_buf_p = yy_cp -= 1; +YY_DO_BEFORE_ACTION; /* set up yytext again */ +YY_RULE_SETUP +#line 81 "pool_config.l" +/* eat comment */ + YY_BREAK +case 4: +YY_RULE_SETUP +#line 83 "pool_config.l" +return POOL_KEY; + YY_BREAK +case 5: +YY_RULE_SETUP +#line 84 "pool_config.l" +return POOL_STRING; + YY_BREAK +case 6: +YY_RULE_SETUP +#line 85 "pool_config.l" +return POOL_UNQUOTED_STRING; + YY_BREAK +case 7: +YY_RULE_SETUP +#line 86 "pool_config.l" +return POOL_INTEGER; + YY_BREAK +case 8: +YY_RULE_SETUP +#line 87 "pool_config.l" +return POOL_REAL; + YY_BREAK +case 9: +YY_RULE_SETUP +#line 88 "pool_config.l" +return POOL_EQUALS; + YY_BREAK +case 10: +YY_RULE_SETUP +#line 90 "pool_config.l" +return POOL_PARSE_ERROR; + YY_BREAK +case 11: +YY_RULE_SETUP +#line 92 "pool_config.l" +ECHO; + YY_BREAK +#line 748 "pool_config.c" +case YY_STATE_EOF(INITIAL): + yyterminate(); + + case YY_END_OF_BUFFER: + { + /* Amount of text matched not including the EOB char. */ + int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1; + + /* Undo the effects of YY_DO_BEFORE_ACTION. */ + *yy_cp = yy_hold_char; + YY_RESTORE_YY_MORE_OFFSET + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW ) + { + /* We're scanning a new file or input source. It's + * possible that this happened because the user + * just pointed yyin at a new source and called + * yylex(). If so, then we have to assure + * consistency between yy_current_buffer and our + * globals. Here is the right place to do so, because + * this is the first action (other than possibly a + * back-up) that will match for the new input source. + */ + yy_n_chars = yy_current_buffer->yy_n_chars; + yy_current_buffer->yy_input_file = yyin; + yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL; + } + + /* Note that here we test for yy_c_buf_p "<=" to the position + * of the first EOB in the buffer, since yy_c_buf_p will + * already have been incremented past the NUL character + * (since all states make transitions on EOB to the + * end-of-buffer state). Contrast this with the test + * in input(). + */ + if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + { /* This was really a NUL. */ + yy_state_type yy_next_state; + + yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + /* Okay, we're now positioned to make the NUL + * transition. We couldn't have + * yy_get_previous_state() go ahead and do it + * for us because it doesn't know how to deal + * with the possibility of jamming (and we don't + * want to build jamming into it because then it + * will run more slowly). + */ + + yy_next_state = yy_try_NUL_trans( yy_current_state ); + + yy_bp = yytext_ptr + YY_MORE_ADJ; + + if ( yy_next_state ) + { + /* Consume the NUL. */ + yy_cp = ++yy_c_buf_p; + yy_current_state = yy_next_state; + goto yy_match; + } + + else + { + yy_cp = yy_c_buf_p; + goto yy_find_action; + } + } + + else switch ( yy_get_next_buffer() ) + { + case EOB_ACT_END_OF_FILE: + { + yy_did_buffer_switch_on_eof = 0; + + if ( yywrap() ) + { + /* Note: because we've taken care in + * yy_get_next_buffer() to have set up + * yytext, we can now set up + * yy_c_buf_p so that if some total + * hoser (like flex itself) wants to + * call the scanner after we return the + * YY_NULL, it'll still work - another + * YY_NULL will get returned. + */ + yy_c_buf_p = yytext_ptr + YY_MORE_ADJ; + + yy_act = YY_STATE_EOF(YY_START); + goto do_action; + } + + else + { + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; + } + break; + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = + yytext_ptr + yy_amount_of_matched_text; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_match; + + case EOB_ACT_LAST_MATCH: + yy_c_buf_p = + &yy_current_buffer->yy_ch_buf[yy_n_chars]; + + yy_current_state = yy_get_previous_state(); + + yy_cp = yy_c_buf_p; + yy_bp = yytext_ptr + YY_MORE_ADJ; + goto yy_find_action; + } + break; + } + + default: + YY_FATAL_ERROR( + "fatal flex scanner internal error--no action found" ); + } /* end of action switch */ + } /* end of scanning one token */ + } /* end of yylex */ + + +/* yy_get_next_buffer - try to read in a new buffer + * + * Returns a code representing an action: + * EOB_ACT_LAST_MATCH - + * EOB_ACT_CONTINUE_SCAN - continue scanning from current position + * EOB_ACT_END_OF_FILE - end of file + */ + +static int yy_get_next_buffer() + { + register char *dest = yy_current_buffer->yy_ch_buf; + register char *source = yytext_ptr; + register int number_to_move, i; + int ret_val; + + if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] ) + YY_FATAL_ERROR( + "fatal flex scanner internal error--end of buffer missed" ); + + if ( yy_current_buffer->yy_fill_buffer == 0 ) + { /* Don't try to fill the buffer, so this is an EOF. */ + if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 ) + { + /* We matched a single character, the EOB, so + * treat this as a final EOF. + */ + return EOB_ACT_END_OF_FILE; + } + + else + { + /* We matched some text prior to the EOB, first + * process it. + */ + return EOB_ACT_LAST_MATCH; + } + } + + /* Try to read more data. */ + + /* First move last chars to start of buffer. */ + number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1; + + for ( i = 0; i < number_to_move; ++i ) + *(dest++) = *(source++); + + if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING ) + /* don't do the read, it's not guaranteed to return an EOF, + * just force an EOF + */ + yy_current_buffer->yy_n_chars = yy_n_chars = 0; + + else + { + int num_to_read = + yy_current_buffer->yy_buf_size - number_to_move - 1; + + while ( num_to_read <= 0 ) + { /* Not enough room in the buffer - grow it. */ +#ifdef YY_USES_REJECT + YY_FATAL_ERROR( +"input buffer overflow, can't enlarge buffer because scanner uses REJECT" ); +#else + + /* just a shorter name for the current buffer */ + YY_BUFFER_STATE b = yy_current_buffer; + + int yy_c_buf_p_offset = + (int) (yy_c_buf_p - b->yy_ch_buf); + + if ( b->yy_is_our_buffer ) + { + int new_size = b->yy_buf_size * 2; + + if ( new_size <= 0 ) + b->yy_buf_size += b->yy_buf_size / 8; + else + b->yy_buf_size *= 2; + + b->yy_ch_buf = (char *) + /* Include room in for 2 EOB chars. */ + yy_flex_realloc( (void *) b->yy_ch_buf, + b->yy_buf_size + 2 ); + } + else + /* Can't grow it, we don't own it. */ + b->yy_ch_buf = 0; + + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( + "fatal error - scanner input buffer overflow" ); + + yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset]; + + num_to_read = yy_current_buffer->yy_buf_size - + number_to_move - 1; +#endif + } + + if ( num_to_read > YY_READ_BUF_SIZE ) + num_to_read = YY_READ_BUF_SIZE; + + /* Read in more data. */ + YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]), + yy_n_chars, num_to_read ); + + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + if ( yy_n_chars == 0 ) + { + if ( number_to_move == YY_MORE_ADJ ) + { + ret_val = EOB_ACT_END_OF_FILE; + yyrestart( yyin ); + } + + else + { + ret_val = EOB_ACT_LAST_MATCH; + yy_current_buffer->yy_buffer_status = + YY_BUFFER_EOF_PENDING; + } + } + + else + ret_val = EOB_ACT_CONTINUE_SCAN; + + yy_n_chars += number_to_move; + yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR; + yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR; + + yytext_ptr = &yy_current_buffer->yy_ch_buf[0]; + + return ret_val; + } + + +/* yy_get_previous_state - get the state just before the EOB char was reached */ + +static yy_state_type yy_get_previous_state() + { + register yy_state_type yy_current_state; + register char *yy_cp; + + yy_current_state = yy_start; + + for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp ) + { + register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 38 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + } + + return yy_current_state; + } + + +/* yy_try_NUL_trans - try to make a transition on the NUL character + * + * synopsis + * next_state = yy_try_NUL_trans( current_state ); + */ + +#ifdef YY_USE_PROTOS +static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state ) +#else +static yy_state_type yy_try_NUL_trans( yy_current_state ) +yy_state_type yy_current_state; +#endif + { + register int yy_is_jam; + register char *yy_cp = yy_c_buf_p; + + register YY_CHAR yy_c = 1; + if ( yy_accept[yy_current_state] ) + { + yy_last_accepting_state = yy_current_state; + yy_last_accepting_cpos = yy_cp; + } + while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) + { + yy_current_state = (int) yy_def[yy_current_state]; + if ( yy_current_state >= 38 ) + yy_c = yy_meta[(unsigned int) yy_c]; + } + yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; + yy_is_jam = (yy_current_state == 37); + + return yy_is_jam ? 0 : yy_current_state; + } + + +#ifndef YY_NO_UNPUT +#ifdef YY_USE_PROTOS +static void yyunput( int c, register char *yy_bp ) +#else +static void yyunput( c, yy_bp ) +int c; +register char *yy_bp; +#endif + { + register char *yy_cp = yy_c_buf_p; + + /* undo effects of setting up yytext */ + *yy_cp = yy_hold_char; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + { /* need to shift things up to make room */ + /* +2 for EOB chars. */ + register int number_to_move = yy_n_chars + 2; + register char *dest = &yy_current_buffer->yy_ch_buf[ + yy_current_buffer->yy_buf_size + 2]; + register char *source = + &yy_current_buffer->yy_ch_buf[number_to_move]; + + while ( source > yy_current_buffer->yy_ch_buf ) + *--dest = *--source; + + yy_cp += (int) (dest - source); + yy_bp += (int) (dest - source); + yy_current_buffer->yy_n_chars = + yy_n_chars = yy_current_buffer->yy_buf_size; + + if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 ) + YY_FATAL_ERROR( "flex scanner push-back overflow" ); + } + + *--yy_cp = (char) c; + + + yytext_ptr = yy_bp; + yy_hold_char = *yy_cp; + yy_c_buf_p = yy_cp; + } +#endif /* ifndef YY_NO_UNPUT */ + + +#ifdef __cplusplus +static int yyinput() +#else +static int input() +#endif + { + int c; + + *yy_c_buf_p = yy_hold_char; + + if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR ) + { + /* yy_c_buf_p now points to the character we want to return. + * If this occurs *before* the EOB characters, then it's a + * valid NUL; if not, then we've hit the end of the buffer. + */ + if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] ) + /* This was really a NUL. */ + *yy_c_buf_p = '\0'; + + else + { /* need more input */ + int offset = yy_c_buf_p - yytext_ptr; + ++yy_c_buf_p; + + switch ( yy_get_next_buffer() ) + { + case EOB_ACT_LAST_MATCH: + /* This happens because yy_g_n_b() + * sees that we've accumulated a + * token and flags that we need to + * try matching the token before + * proceeding. But for input(), + * there's no matching to consider. + * So convert the EOB_ACT_LAST_MATCH + * to EOB_ACT_END_OF_FILE. + */ + + /* Reset buffer status. */ + yyrestart( yyin ); + + /* fall through */ + + case EOB_ACT_END_OF_FILE: + { + if ( yywrap() ) + return EOF; + + if ( ! yy_did_buffer_switch_on_eof ) + YY_NEW_FILE; +#ifdef __cplusplus + return yyinput(); +#else + return input(); +#endif + } + + case EOB_ACT_CONTINUE_SCAN: + yy_c_buf_p = yytext_ptr + offset; + break; + } + } + } + + c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */ + *yy_c_buf_p = '\0'; /* preserve yytext */ + yy_hold_char = *++yy_c_buf_p; + + + return c; + } + + +#ifdef YY_USE_PROTOS +void yyrestart( FILE *input_file ) +#else +void yyrestart( input_file ) +FILE *input_file; +#endif + { + if ( ! yy_current_buffer ) + yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); + + yy_init_buffer( yy_current_buffer, input_file ); + yy_load_buffer_state(); + } + + +#ifdef YY_USE_PROTOS +void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer ) +#else +void yy_switch_to_buffer( new_buffer ) +YY_BUFFER_STATE new_buffer; +#endif + { + if ( yy_current_buffer == new_buffer ) + return; + + if ( yy_current_buffer ) + { + /* Flush out information for old buffer. */ + *yy_c_buf_p = yy_hold_char; + yy_current_buffer->yy_buf_pos = yy_c_buf_p; + yy_current_buffer->yy_n_chars = yy_n_chars; + } + + yy_current_buffer = new_buffer; + yy_load_buffer_state(); + + /* We don't actually know whether we did this switch during + * EOF (yywrap()) processing, but the only time this flag + * is looked at is after yywrap() is called, so it's safe + * to go ahead and always set it. + */ + yy_did_buffer_switch_on_eof = 1; + } + + +#ifdef YY_USE_PROTOS +void yy_load_buffer_state( void ) +#else +void yy_load_buffer_state() +#endif + { + yy_n_chars = yy_current_buffer->yy_n_chars; + yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos; + yyin = yy_current_buffer->yy_input_file; + yy_hold_char = *yy_c_buf_p; + } + + +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_create_buffer( FILE *file, int size ) +#else +YY_BUFFER_STATE yy_create_buffer( file, size ) +FILE *file; +int size; +#endif + { + YY_BUFFER_STATE b; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_buf_size = size; + + /* yy_ch_buf has to be 2 characters longer than the size given because + * we need to put in 2 end-of-buffer characters. + */ + b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 ); + if ( ! b->yy_ch_buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); + + b->yy_is_our_buffer = 1; + + yy_init_buffer( b, file ); + + return b; + } + + +#ifdef YY_USE_PROTOS +void yy_delete_buffer( YY_BUFFER_STATE b ) +#else +void yy_delete_buffer( b ) +YY_BUFFER_STATE b; +#endif + { + if ( ! b ) + return; + + if ( b == yy_current_buffer ) + yy_current_buffer = (YY_BUFFER_STATE) 0; + + if ( b->yy_is_our_buffer ) + yy_flex_free( (void *) b->yy_ch_buf ); + + yy_flex_free( (void *) b ); + } + + + +#ifdef YY_USE_PROTOS +void yy_init_buffer( YY_BUFFER_STATE b, FILE *file ) +#else +void yy_init_buffer( b, file ) +YY_BUFFER_STATE b; +FILE *file; +#endif + + + { + yy_flush_buffer( b ); + + b->yy_input_file = file; + b->yy_fill_buffer = 1; + +#if YY_ALWAYS_INTERACTIVE + b->yy_is_interactive = 1; +#else +#if YY_NEVER_INTERACTIVE + b->yy_is_interactive = 0; +#else + b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; +#endif +#endif + } + + +#ifdef YY_USE_PROTOS +void yy_flush_buffer( YY_BUFFER_STATE b ) +#else +void yy_flush_buffer( b ) +YY_BUFFER_STATE b; +#endif + + { + if ( ! b ) + return; + + b->yy_n_chars = 0; + + /* We always need two end-of-buffer characters. The first causes + * a transition to the end-of-buffer state. The second causes + * a jam in that state. + */ + b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; + b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; + + b->yy_buf_pos = &b->yy_ch_buf[0]; + + b->yy_at_bol = 1; + b->yy_buffer_status = YY_BUFFER_NEW; + + if ( b == yy_current_buffer ) + yy_load_buffer_state(); + } + + +#ifndef YY_NO_SCAN_BUFFER +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size ) +#else +YY_BUFFER_STATE yy_scan_buffer( base, size ) +char *base; +yy_size_t size; +#endif + { + YY_BUFFER_STATE b; + + if ( size < 2 || + base[size-2] != YY_END_OF_BUFFER_CHAR || + base[size-1] != YY_END_OF_BUFFER_CHAR ) + /* They forgot to leave room for the EOB's. */ + return 0; + + b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) ); + if ( ! b ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); + + b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ + b->yy_buf_pos = b->yy_ch_buf = base; + b->yy_is_our_buffer = 0; + b->yy_input_file = 0; + b->yy_n_chars = b->yy_buf_size; + b->yy_is_interactive = 0; + b->yy_at_bol = 1; + b->yy_fill_buffer = 0; + b->yy_buffer_status = YY_BUFFER_NEW; + + yy_switch_to_buffer( b ); + + return b; + } +#endif + + +#ifndef YY_NO_SCAN_STRING +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str ) +#else +YY_BUFFER_STATE yy_scan_string( yy_str ) +yyconst char *yy_str; +#endif + { + int len; + for ( len = 0; yy_str[len]; ++len ) + ; + + return yy_scan_bytes( yy_str, len ); + } +#endif + + +#ifndef YY_NO_SCAN_BYTES +#ifdef YY_USE_PROTOS +YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len ) +#else +YY_BUFFER_STATE yy_scan_bytes( bytes, len ) +yyconst char *bytes; +int len; +#endif + { + YY_BUFFER_STATE b; + char *buf; + yy_size_t n; + int i; + + /* Get memory for full buffer, including space for trailing EOB's. */ + n = len + 2; + buf = (char *) yy_flex_alloc( n ); + if ( ! buf ) + YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); + + for ( i = 0; i < len; ++i ) + buf[i] = bytes[i]; + + buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR; + + b = yy_scan_buffer( buf, n ); + if ( ! b ) + YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); + + /* It's okay to grow etc. this buffer, and we should throw it + * away when we're done. + */ + b->yy_is_our_buffer = 1; + + return b; + } +#endif + + +#ifndef YY_NO_PUSH_STATE +#ifdef YY_USE_PROTOS +static void yy_push_state( int new_state ) +#else +static void yy_push_state( new_state ) +int new_state; +#endif + { + if ( yy_start_stack_ptr >= yy_start_stack_depth ) + { + yy_size_t new_size; + + yy_start_stack_depth += YY_START_STACK_INCR; + new_size = yy_start_stack_depth * sizeof( int ); + + if ( ! yy_start_stack ) + yy_start_stack = (int *) yy_flex_alloc( new_size ); + + else + yy_start_stack = (int *) yy_flex_realloc( + (void *) yy_start_stack, new_size ); + + if ( ! yy_start_stack ) + YY_FATAL_ERROR( + "out of memory expanding start-condition stack" ); + } + + yy_start_stack[yy_start_stack_ptr++] = YY_START; + + BEGIN(new_state); + } +#endif + + +#ifndef YY_NO_POP_STATE +static void yy_pop_state() + { + if ( --yy_start_stack_ptr < 0 ) + YY_FATAL_ERROR( "start-condition stack underflow" ); + + BEGIN(yy_start_stack[yy_start_stack_ptr]); + } +#endif + + +#ifndef YY_NO_TOP_STATE +static int yy_top_state() + { + return yy_start_stack[yy_start_stack_ptr - 1]; + } +#endif + +#ifndef YY_EXIT_FAILURE +#define YY_EXIT_FAILURE 2 +#endif + +#ifdef YY_USE_PROTOS +static void yy_fatal_error( yyconst char msg[] ) +#else +static void yy_fatal_error( msg ) +char msg[]; +#endif + { + (void) fprintf( stderr, "%s\n", msg ); + exit( YY_EXIT_FAILURE ); + } + + + +/* Redefine yyless() so it works in section 3 code. */ + +#undef yyless +#define yyless(n) \ + do \ + { \ + /* Undo effects of setting up yytext. */ \ + yytext[yyleng] = yy_hold_char; \ + yy_c_buf_p = yytext + n; \ + yy_hold_char = *yy_c_buf_p; \ + *yy_c_buf_p = '\0'; \ + yyleng = n; \ + } \ + while ( 0 ) + + +/* Internal utility routines. */ + +#ifndef yytext_ptr +#ifdef YY_USE_PROTOS +static void yy_flex_strncpy( char *s1, yyconst char *s2, int n ) +#else +static void yy_flex_strncpy( s1, s2, n ) +char *s1; +yyconst char *s2; +int n; +#endif + { + register int i; + for ( i = 0; i < n; ++i ) + s1[i] = s2[i]; + } +#endif + +#ifdef YY_NEED_STRLEN +#ifdef YY_USE_PROTOS +static int yy_flex_strlen( yyconst char *s ) +#else +static int yy_flex_strlen( s ) +yyconst char *s; +#endif + { + register int n; + for ( n = 0; s[n]; ++n ) + ; + + return n; + } +#endif + + +#ifdef YY_USE_PROTOS +static void *yy_flex_alloc( yy_size_t size ) +#else +static void *yy_flex_alloc( size ) +yy_size_t size; +#endif + { + return (void *) malloc( size ); + } + +#ifdef YY_USE_PROTOS +static void *yy_flex_realloc( void *ptr, yy_size_t size ) +#else +static void *yy_flex_realloc( ptr, size ) +void *ptr; +yy_size_t size; +#endif + { + /* The cast to (char *) in the following accommodates both + * implementations that use char* generic pointers, and those + * that use void* generic pointers. It works with the latter + * because both ANSI C and C++ allow castless assignment from + * any pointer type to void*, and deal with argument conversions + * as though doing an assignment. + */ + return (void *) realloc( (char *) ptr, size ); + } + +#ifdef YY_USE_PROTOS +static void yy_flex_free( void *ptr ) +#else +static void yy_flex_free( ptr ) +void *ptr; +#endif + { + free( ptr ); + } + +#if YY_MAIN +int main() + { + yylex(); + return 0; + } +#endif +#line 92 "pool_config.l" + + +static int eval_logical(char *str); + +int pool_get_config(char *confpath) +{ + FILE *fd; + int token; + char key[1024]; + static char *default_reset_query_list[] = {"ABORT", "RESET ALL", "SET SESSION AUTHORIZATION DEFAULT"}; + + /* set hardcoded default values */ + pool_config.listen_addresses = "localhost"; + pool_config.port = 9999; + pool_config.socket_dir = DEFAULT_SOCKET_DIR; + pool_config.backend_host_name = ""; + pool_config.backend_port = 5432; + pool_config.backend_socket_dir = DEFAULT_SOCKET_DIR; + pool_config.secondary_backend_host_name = ""; + pool_config.secondary_backend_port = 0; /* no secondary backend */ + pool_config.num_init_children = 32; + pool_config.child_life_time = 300; + pool_config.connection_life_time = 0; + pool_config.max_pool = 4; + pool_config.logdir = DEFAULT_LOGDIR; + + pool_config.current_backend_host_name = ""; + pool_config.current_backend_port = 5432; + + pool_config.replication_mode = 0; + pool_config.replication_strict = 1; + pool_config.replication_timeout = 0; + pool_config.load_balance_mode = 0; + pool_config.replication_stop_on_mismatch = 0; + pool_config.weight_master = 0.5; + pool_config.weight_secondary = 0.5; + pool_config.reset_query_list = default_reset_query_list; + pool_config.num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *); + pool_config.reset_query_list = default_reset_query_list; + pool_config.print_timestamp = 1; + pool_config.master_slave_mode = 0; + pool_config.connection_cache = 1; + pool_config.health_check_timeout = 20; + pool_config.health_check_period = 0; + pool_config.health_check_user = "nobody"; + +#define PARSE_ERROR() pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext) + + /* open config file */ + fd = fopen(confpath, "r"); + if (!fd) + { + fprintf(stderr, "pool_config: could not open configuration file (%s)\n", + POOL_CONF_FILE_NAME); + fprintf(stderr, "pool_config: using default values...\n"); + return 0; + } + + yyin = fd; + Lineno = 1; + + while ((token = yylex())) + { + if (token == POOL_PARSE_ERROR) + { + PARSE_ERROR(); + return(-1); + } + if (token == POOL_EOL) + continue; + + if (token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + + strncpy(key, yytext, sizeof(key)); + + pool_debug("key: %s", key); + + token = yylex(); + + if (token == POOL_EQUALS) + token = yylex(); + + pool_debug("value: %s kind: %d", yytext, token); + + if (!strcmp(key, "allow_inet_domain_socket")) + { + /* for backward compatibility */ + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + if (v) + pool_config.listen_addresses = strdup("*"); + else + pool_config.listen_addresses = strdup(""); + } + else if (!strcmp(key, "listen_addresses")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.listen_addresses = str; + } + + else if (!strcmp(key, "port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1024) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.port = v; + } + else if (!strcmp(key, "socket_dir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.socket_dir = str; + } + else if (!strcmp(key, "backend_host_name")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.backend_host_name = str; + pool_debug(":%s:", pool_config.backend_host_name); + } + else if (!strcmp(key, "backend_port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1024) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.backend_port = v; + } + else if (!strcmp(key, "secondary_backend_host_name")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.secondary_backend_host_name = str; + pool_debug(":%s:", pool_config.secondary_backend_host_name); + } + else if (!strcmp(key, "secondary_backend_port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || (v != 0 && v < 1024)) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.secondary_backend_port = v; + } + else if (!strcmp(key, "num_init_children")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1) + { + pool_error("pool_config: %s must be higher than 1 numeric value", key); + return(-1); + } + pool_config.num_init_children = v; + } + else if (!strcmp(key, "child_life_time")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.child_life_time = v; + } + else if (!strcmp(key, "connection_life_time")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.connection_life_time = v; + } + else if (!strcmp(key, "max_pool")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.max_pool = v; + } + else if (!strcmp(key, "logdir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.logdir = str; + } + else if (!strcmp(key, "backend_socket_dir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.backend_socket_dir = str; + } + else if (!strcmp(key, "replication_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.replication_mode = pool_config.replication_enabled = v; + + if (pool_config.master_slave_enabled && pool_config.replication_enabled) + { + pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); + return(-1); + } + + } + else if (!strcmp(key, "replication_strict")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.replication_strict = v; + } + else if (!strcmp(key, "replication_timeout")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.replication_timeout = v; + } + else if (!strcmp(key, "load_balance_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.load_balance_mode = v; + } + else if (!strcmp(key, "replication_stop_on_mismatch")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_debug("replication_stop_on_mismatch: %d", v); + pool_config.replication_stop_on_mismatch = v; + } + else if (!strcmp(key, "weight_master")) + { + double v = atof(yytext); + + if (v < 0.0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + + pool_debug("weight_master: %f", v); + pool_config.weight_master = v; + } + else if (!strcmp(key, "weight_secondary")) + { + double v = atof(yytext); + + if (v < 0.0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + + pool_debug("weight_secondary: %f", v); + pool_config.weight_secondary = v; + } + + else if (!strcmp(key, "reset_query_list")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.reset_query_list = extract_string_tokens(str, ";", &pool_config.num_reset_queries); + if (pool_config.reset_query_list == NULL) + { + return(-1); + } + } + + if (pool_config.weight_master == 0.0 && pool_config.weight_secondary == 0.0) + { + pool_error("pool_config: both of weight_master and weight_secondary cannot be 0"); + return(-1); + } + + else if (!strcmp(key, "print_timestamp")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.print_timestamp = v; + } + + else if (!strcmp(key, "master_slave_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.master_slave_mode = pool_config.master_slave_enabled = v; + + if (pool_config.master_slave_enabled && pool_config.replication_enabled) + { + pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); + return(-1); + } + } + + else if (!strcmp(key, "connection_cache")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.connection_cache = v; + } + + else if (!strcmp(key, "health_check_timeout")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); + return(-1); + } + pool_config.health_check_timeout = v; + } + + else if (!strcmp(key, "health_check_period")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); + return(-1); + } + pool_config.health_check_period = v; + } + + else if (!strcmp(key, "health_check_user")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.health_check_user = str; + } + } + + return 0; +} + +static char *extract_string(char *value, POOL_TOKEN token) +{ + char *ret; + + ret = strdup(value); + if (!ret) + { + pool_error("extract_string: out of memory"); + return NULL; + } + + if (token == POOL_STRING) + { + ret[strlen(ret)-1] = '\0'; + return (ret+1); + } + return ret; +} + +static int eval_logical(char *str) +{ + int ret; + + if (!strcasecmp(str, "true")) + ret = 1; + else if (!strcasecmp(str, "false")) + ret = 0; + else if (!strcmp(str, "1")) + ret = 1; + else if (!strcmp(str, "0")) + ret = 0; + else + ret = -1; + + return ret; +} + +/* + * extract tokens separated by ',' from str. number of tokens are set + * to n; note that str will be destroyed. Also return value points to + * static data, that means subsequent call will change the return + * value. + */ +#define MAXTOKENS 1024 +static char **extract_string_tokens(char *str, char *delimi, int *n) +{ + char *token; + static char *tokens[MAXTOKENS]; + + *n = 0; + + while ((token = strsep(&str, delimi)) && *n < MAXTOKENS) + { + tokens[*n] = strdup(token); + if (tokens[*n] == NULL) + { + pool_error("extract_string_tokens: out of memory"); + return NULL; + } + pool_debug("extract_string_tokens: token: %s", tokens[*n]); + (*n)++; + } + return tokens; +} diff --git a/pool_config.l b/pool_config.l new file mode 100644 index 0000000..4e4883a --- /dev/null +++ b/pool_config.l @@ -0,0 +1,638 @@ +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_config.l: read configuration file + * + */ + +%{ + +#include "pool.h" + +#include +#include + +/* to shut off compiler warnings */ +int yylex(void); + +POOL_CONFIG pool_config; /* configuration values */ +static unsigned Lineno; + +typedef enum { + POOL_KEY = 1, + POOL_INTEGER, + POOL_REAL, + POOL_STRING, + POOL_UNQUOTED_STRING, + POOL_EQUALS, + POOL_EOL, + POOL_PARSE_ERROR +} POOL_TOKEN; + +static char *extract_string(char *value, POOL_TOKEN token); +static char **extract_string_tokens(char *str, char *delim, int *n); + +%} + +%option 8bit +%option never-interactive +%option nounput +%option noyywrap + +SIGN ("-"|"+") +DIGIT [0-9] +HEXDIGIT [0-9a-fA-F] + +INTEGER {SIGN}?({DIGIT}+|0x{HEXDIGIT}+) + +EXPONENT [Ee]{SIGN}?{DIGIT}+ +REAL {SIGN}?{DIGIT}*"."{DIGIT}*{EXPONENT}? + +LETTER [A-Za-z_\200-\377] +LETTER_OR_DIGIT [A-Za-z_0-9\200-\377] + +KEY {LETTER}{LETTER_OR_DIGIT}* + +UNQUOTED_STRING {LETTER}({LETTER_OR_DIGIT}|[-._:/])* +STRING \'([^'\n]|\\.)*\' + +%% + +\n Lineno++; return POOL_EOL; +[ \t\r]+ /* eat whitespace */ +#.*$ /* eat comment */ + +{KEY} return POOL_KEY; +{STRING} return POOL_STRING; +{UNQUOTED_STRING} return POOL_UNQUOTED_STRING; +{INTEGER} return POOL_INTEGER; +{REAL} return POOL_REAL; += return POOL_EQUALS; + +. return POOL_PARSE_ERROR; + +%% + +static int eval_logical(char *str); + +int pool_get_config(char *confpath) +{ + FILE *fd; + int token; + char key[1024]; + static char *default_reset_query_list[] = {"ABORT", "RESET ALL", "SET SESSION AUTHORIZATION DEFAULT"}; + + /* set hardcoded default values */ + pool_config.listen_addresses = "localhost"; + pool_config.port = 9999; + pool_config.socket_dir = DEFAULT_SOCKET_DIR; + pool_config.backend_host_name = ""; + pool_config.backend_port = 5432; + pool_config.backend_socket_dir = DEFAULT_SOCKET_DIR; + pool_config.secondary_backend_host_name = ""; + pool_config.secondary_backend_port = 0; /* no secondary backend */ + pool_config.num_init_children = 32; + pool_config.child_life_time = 300; + pool_config.connection_life_time = 0; + pool_config.max_pool = 4; + pool_config.logdir = DEFAULT_LOGDIR; + + pool_config.current_backend_host_name = ""; + pool_config.current_backend_port = 5432; + + pool_config.replication_mode = 0; + pool_config.replication_strict = 1; + pool_config.replication_timeout = 0; + pool_config.load_balance_mode = 0; + pool_config.replication_stop_on_mismatch = 0; + pool_config.weight_master = 0.5; + pool_config.weight_secondary = 0.5; + pool_config.reset_query_list = default_reset_query_list; + pool_config.num_reset_queries = sizeof(default_reset_query_list)/sizeof(char *); + pool_config.reset_query_list = default_reset_query_list; + pool_config.print_timestamp = 1; + pool_config.master_slave_mode = 0; + pool_config.connection_cache = 1; + pool_config.health_check_timeout = 20; + pool_config.health_check_period = 0; + pool_config.health_check_user = "nobody"; + +#define PARSE_ERROR() pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext) + + /* open config file */ + fd = fopen(confpath, "r"); + if (!fd) + { + fprintf(stderr, "pool_config: could not open configuration file (%s)\n", + POOL_CONF_FILE_NAME); + fprintf(stderr, "pool_config: using default values...\n"); + return 0; + } + + yyin = fd; + Lineno = 1; + + while ((token = yylex())) + { + if (token == POOL_PARSE_ERROR) + { + PARSE_ERROR(); + return(-1); + } + if (token == POOL_EOL) + continue; + + if (token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + + strncpy(key, yytext, sizeof(key)); + + pool_debug("key: %s", key); + + token = yylex(); + + if (token == POOL_EQUALS) + token = yylex(); + + pool_debug("value: %s kind: %d", yytext, token); + + if (!strcmp(key, "allow_inet_domain_socket")) + { + /* for backward compatibility */ + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + if (v) + pool_config.listen_addresses = strdup("*"); + else + pool_config.listen_addresses = strdup(""); + } + else if (!strcmp(key, "listen_addresses")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.listen_addresses = str; + } + + else if (!strcmp(key, "port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1024) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.port = v; + } + else if (!strcmp(key, "socket_dir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.socket_dir = str; + } + else if (!strcmp(key, "backend_host_name")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.backend_host_name = str; + pool_debug(":%s:", pool_config.backend_host_name); + } + else if (!strcmp(key, "backend_port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1024) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.backend_port = v; + } + else if (!strcmp(key, "secondary_backend_host_name")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.secondary_backend_host_name = str; + pool_debug(":%s:", pool_config.secondary_backend_host_name); + } + else if (!strcmp(key, "secondary_backend_port")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || (v != 0 && v < 1024)) + { + pool_error("pool_config: %s must be 1024 or higher numeric value", key); + return(-1); + } + pool_config.secondary_backend_port = v; + } + else if (!strcmp(key, "num_init_children")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 1) + { + pool_error("pool_config: %s must be higher than 1 numeric value", key); + return(-1); + } + pool_config.num_init_children = v; + } + else if (!strcmp(key, "child_life_time")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.child_life_time = v; + } + else if (!strcmp(key, "connection_life_time")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.connection_life_time = v; + } + else if (!strcmp(key, "max_pool")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.max_pool = v; + } + else if (!strcmp(key, "logdir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.logdir = str; + } + else if (!strcmp(key, "backend_socket_dir")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.backend_socket_dir = str; + } + else if (!strcmp(key, "replication_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.replication_mode = pool_config.replication_enabled = v; + + if (pool_config.master_slave_enabled && pool_config.replication_enabled) + { + pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); + return(-1); + } + + } + else if (!strcmp(key, "replication_strict")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.replication_strict = v; + } + else if (!strcmp(key, "replication_timeout")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be higher than 0 numeric value", key); + return(-1); + } + pool_config.replication_timeout = v; + } + else if (!strcmp(key, "load_balance_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.load_balance_mode = v; + } + else if (!strcmp(key, "replication_stop_on_mismatch")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_debug("replication_stop_on_mismatch: %d", v); + pool_config.replication_stop_on_mismatch = v; + } + else if (!strcmp(key, "weight_master")) + { + double v = atof(yytext); + + if (v < 0.0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + + pool_debug("weight_master: %f", v); + pool_config.weight_master = v; + } + else if (!strcmp(key, "weight_secondary")) + { + double v = atof(yytext); + + if (v < 0.0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + + pool_debug("weight_secondary: %f", v); + pool_config.weight_secondary = v; + } + + else if (!strcmp(key, "reset_query_list")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.reset_query_list = extract_string_tokens(str, ";", &pool_config.num_reset_queries); + if (pool_config.reset_query_list == NULL) + { + return(-1); + } + } + + if (pool_config.weight_master == 0.0 && pool_config.weight_secondary == 0.0) + { + pool_error("pool_config: both of weight_master and weight_secondary cannot be 0"); + return(-1); + } + + else if (!strcmp(key, "print_timestamp")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.print_timestamp = v; + } + + else if (!strcmp(key, "master_slave_mode")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.master_slave_mode = pool_config.master_slave_enabled = v; + + if (pool_config.master_slave_enabled && pool_config.replication_enabled) + { + pool_error("pool_config: replication_mode and master_slave_mode cannot be enabled at the same time"); + return(-1); + } + } + + else if (!strcmp(key, "connection_cache")) + { + int v = eval_logical(yytext); + + if (v < 0) + { + pool_error("pool_config: invalid value %s for %s", yytext, key); + return(-1); + } + pool_config.connection_cache = v; + } + + else if (!strcmp(key, "health_check_timeout")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); + return(-1); + } + pool_config.health_check_timeout = v; + } + + else if (!strcmp(key, "health_check_period")) + { + int v = atoi(yytext); + + if (token != POOL_INTEGER || v < 0) + { + pool_error("pool_config: %s must be equal or higher than 0 numeric value", key); + return(-1); + } + pool_config.health_check_period = v; + } + + else if (!strcmp(key, "health_check_user")) + { + char *str; + + if (token != POOL_STRING && token != POOL_UNQUOTED_STRING && token != POOL_KEY) + { + PARSE_ERROR(); + return(-1); + } + str = extract_string(yytext, token); + if (str == NULL) + { + return(-1); + } + pool_config.health_check_user = str; + } + } + + return 0; +} + +static char *extract_string(char *value, POOL_TOKEN token) +{ + char *ret; + + ret = strdup(value); + if (!ret) + { + pool_error("extract_string: out of memory"); + return NULL; + } + + if (token == POOL_STRING) + { + ret[strlen(ret)-1] = '\0'; + return (ret+1); + } + return ret; +} + +static int eval_logical(char *str) +{ + int ret; + + if (!strcasecmp(str, "true")) + ret = 1; + else if (!strcasecmp(str, "false")) + ret = 0; + else if (!strcmp(str, "1")) + ret = 1; + else if (!strcmp(str, "0")) + ret = 0; + else + ret = -1; + + return ret; +} + +/* + * extract tokens separated by ',' from str. number of tokens are set + * to n; note that str will be destroyed. Also return value points to + * static data, that means subsequent call will change the return + * value. + */ +#define MAXTOKENS 1024 +static char **extract_string_tokens(char *str, char *delimi, int *n) +{ + char *token; + static char *tokens[MAXTOKENS]; + + *n = 0; + + while ((token = strsep(&str, delimi)) && *n < MAXTOKENS) + { + tokens[*n] = strdup(token); + if (tokens[*n] == NULL) + { + pool_error("extract_string_tokens: out of memory"); + return NULL; + } + pool_debug("extract_string_tokens: token: %s", tokens[*n]); + (*n)++; + } + return tokens; +} diff --git a/pool_connection_pool.c b/pool_connection_pool.c new file mode 100644 index 0000000..5a8085e --- /dev/null +++ b/pool_connection_pool.c @@ -0,0 +1,453 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * poo_connection_pool.c: connection pool stuff + */ +#include "config.h" + +#include +#include +#include +#include +#ifdef HAVE_NETINET_TCP_H +#include +#endif +#include + +#include +#include +#include +#include +#include +#include + +#include "pool.h" + +POOL_CONNECTION_POOL *pool_connection_pool; /* connection pool */ + +static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int secondary_backend); +static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p); + +/* +* initialize connection pools. this should be called once at the startup. +*/ +int pool_init_cp(void) +{ + pool_connection_pool = (POOL_CONNECTION_POOL *)malloc(sizeof(POOL_CONNECTION_POOL)*pool_config.max_pool); + if (pool_connection_pool == NULL) + { + pool_error("pool_init_cp: malloc() failed"); + return -1; + } + memset(pool_connection_pool, 0, sizeof(POOL_CONNECTION_POOL)*pool_config.max_pool); + + return 0; +} + +/* +* find connection by user and database +*/ +POOL_CONNECTION_POOL *pool_get_cp(char *user, char *database, int protoMajor) +{ + int i; + + POOL_CONNECTION_POOL *p = pool_connection_pool; + + if (p == NULL) + { + pool_error("pool_get_cp: pool_connection_pool is not initialized"); + return NULL; + } + + for (i=0;isp->major == protoMajor && + MASTER_CONNECTION(p)->sp->user != NULL && + strcmp(MASTER_CONNECTION(p)->sp->user, user) == 0 && + strcmp(MASTER_CONNECTION(p)->sp->database, database) == 0) + { + /* mark this connection is under use */ + MASTER_CONNECTION(p)->closetime = 0; + return p; + } + p++; + } + return NULL; +} + +/* + * disconnect and release a connection to the database + */ +void pool_discard_cp(char *user, char *database, int protoMajor) +{ + POOL_CONNECTION_POOL *p = pool_get_cp(user, database, protoMajor); + + if (p == NULL) + { + pool_error("pool_discard_cp: cannot get connection pool for user %s datbase %s", user, database); + return; + } + + pool_free_startup_packet(MASTER_CONNECTION(p)->sp); + pool_close(MASTER_CONNECTION(p)->con); + + if (DUAL_MODE) + { + /* do not free memory! we did not allocate them */ + pool_close(SECONDARY_CONNECTION(p)->con); + } + + memset(p, 0, sizeof(POOL_CONNECTION_POOL)); +} + + +/* +* create a connection pool by user and database +*/ +POOL_CONNECTION_POOL *pool_create_cp(void) +{ + int i; + time_t closetime; + POOL_CONNECTION_POOL *oldestp; + + POOL_CONNECTION_POOL *p = pool_connection_pool; + + if (p == NULL) + { + pool_error("pool_create_cp: pool_connection_pool is not initialized"); + return NULL; + } + + for (i=0;iclosetime; + for (i=0;isp->user, + MASTER_CONNECTION(p)->sp->database, + MASTER_CONNECTION(p)->closetime); + if (MASTER_CONNECTION(p)->closetime < closetime) + { + closetime = MASTER_CONNECTION(p)->closetime; + oldestp = p; + } + p++; + } + + p = oldestp; + pool_send_frontend_exits(p); + + pool_debug("discarding old %d th connection. user: %s database: %s", + oldestp - pool_connection_pool, + MASTER_CONNECTION(p)->sp->user, + MASTER_CONNECTION(p)->sp->database); + + pool_free_startup_packet(MASTER_CONNECTION(p)->sp); + pool_close(MASTER_CONNECTION(p)->con); + + if (DUAL_MODE) + { + /* do not free memory! we did not allocate them */ + pool_close(SECONDARY_CONNECTION(p)->con); + } + + memset(p, 0, sizeof(POOL_CONNECTION_POOL)); + + return new_connection(p); +} + +/* + * set backend connection close timer + */ +void pool_connection_pool_timer(POOL_CONNECTION_POOL *backend) +{ + POOL_CONNECTION_POOL *p = pool_connection_pool; + int i; + + pool_debug("pool_connection_pool_timer: called"); + + MASTER_CONNECTION(backend)->closetime = time(NULL); /* set connection close time */ + + if (pool_config.connection_life_time == 0) + return; + + /* look for any other timeout */ + for (i=0;isp->user == NULL) + continue; + + if (p != backend && MASTER_CONNECTION(p)->closetime) + return; + } + + /* no other timer found. set my timer */ + pool_debug("pool_connection_pool_timer: set alarm after %d seconds", pool_config.connection_life_time); + pool_signal(SIGALRM, pool_backend_timer_handler); + alarm(pool_config.connection_life_time); +} + +/* + * backend connection close timer handler + */ +RETSIGTYPE pool_backend_timer_handler(int sig) +{ +#define TMINTMAX 0x7fffffff + + POOL_CONNECTION_POOL *p = pool_connection_pool; + int i; + time_t now; + time_t nearest = TMINTMAX; + + POOL_SETMASK(&BlockSig); + + now = time(NULL); + + pool_debug("pool_backend_timer_handler called at %d", now); + + for (i=0;isp->user == NULL) + continue; + + /* timer expire? */ + if (MASTER_CONNECTION(p)->closetime) + { + pool_debug("pool_backend_timer_handler: expire time: %d", + MASTER_CONNECTION(p)->closetime+pool_config.connection_life_time); + + if (now >= (MASTER_CONNECTION(p)->closetime+pool_config.connection_life_time)) + { + /* discard expired connection */ + pool_debug("pool_backend_timer_handler: expires user %s database %s", MASTER_CONNECTION(p)->sp->user, MASTER_CONNECTION(p)->sp->database); + + pool_send_frontend_exits(p); + + pool_free_startup_packet(MASTER_CONNECTION(p)->sp); + pool_close(MASTER_CONNECTION(p)->con); + + if (DUAL_MODE) + { + /* do not free memory! we did not allocate them */ + pool_close(SECONDARY_CONNECTION(p)->con); + } + + memset(p, 0, sizeof(POOL_CONNECTION_POOL)); + } + else + { + /* look for nearest timer */ + if (MASTER_CONNECTION(p)->closetime < nearest) + nearest = MASTER_CONNECTION(p)->closetime; + } + } + } + + /* any remaining timer */ + if (nearest != TMINTMAX) + { + nearest = pool_config.connection_life_time - (now - nearest); + if (nearest <= 0) + nearest = 1; + pool_signal(SIGALRM, pool_backend_timer_handler); + alarm(nearest); + } + + POOL_SETMASK(&UnBlockSig); +} + +int connect_inet_domain_socket(int secondary_backend) +{ + int fd; + int len; + int on = 1; + struct sockaddr_in addr; + struct hostent *hp; + int port; + char *host; + + fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) + { + pool_error("connect_inet_domain_socket: socket() failed: %s", strerror(errno)); + return -1; + } + + /* set nodelay */ + if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, + (char *) &on, + sizeof(on)) < 0) + { + pool_error("connect_inet_domain_socket: setsockopt() failed: %s", strerror(errno)); + close(fd); + return -1; + } + + memset((char *) &addr, 0, sizeof(addr)); + ((struct sockaddr *)&addr)->sa_family = AF_INET; + + host = secondary_backend?pool_config.secondary_backend_host_name:pool_config.current_backend_host_name; + + port = secondary_backend?pool_config.secondary_backend_port:pool_config.current_backend_port; + addr.sin_port = htons(port); + len = sizeof(struct sockaddr_in); + + hp = gethostbyname(host); + if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + { + pool_error("connect_inet_domain_socket: gethostbyname() failed: %s host: %s", strerror(errno), host); + close(fd); + return -1; + } + memmove((char *) &(addr.sin_addr), + (char *) hp->h_addr, + hp->h_length); + + if (connect(fd, (struct sockaddr *)&addr, len) < 0) + { + pool_error("connect_inet_domain_socket: connect() failed: %s",strerror(errno)); + close(fd); + return -1; + } + return fd; +} + +int connect_unix_domain_socket(int secondary_backend) +{ + struct sockaddr_un addr; + int fd; + int len; + int port; + char *socket_dir; + + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + { + pool_error("connect_unix_domain_socket: setsockopt() failed: %s", strerror(errno)); + return -1; + } + + port = secondary_backend?pool_config.secondary_backend_port:pool_config.current_backend_port; + socket_dir = pool_config.backend_socket_dir; + memset((char *) &addr, 0, sizeof(addr)); + ((struct sockaddr *)&addr)->sa_family = AF_UNIX; + snprintf(addr.sun_path, sizeof(addr.sun_path), "%s/.s.PGSQL.%d", socket_dir, port); + pool_debug("connecting postmaster Unix domain socket: %s", addr.sun_path); + + len = sizeof(struct sockaddr_un); + + if (connect(fd, (struct sockaddr *)&addr, len) < 0) + { + pool_error("connect_unix_domain_socket: connect() failed: %s", strerror(errno)); + close(fd); + return -1; + } + pool_debug("connected to postmaster Unix domain socket: %s fd: %d", addr.sun_path, fd); + return fd; +} + +static POOL_CONNECTION_POOL_SLOT *create_cp(POOL_CONNECTION_POOL_SLOT *cp, int secondary_backend) +{ + int fd; + + if (secondary_backend) + { + if (*pool_config.secondary_backend_host_name == '\0') + fd = connect_unix_domain_socket(1); + else + fd = connect_inet_domain_socket(1); + } + else + { + if (*pool_config.current_backend_host_name == '\0') + fd = connect_unix_domain_socket(0); + else + fd = connect_inet_domain_socket(0); + } + + if (fd < 0) + { + /* fatal error, notice to parent and exit */ + notice_backend_error(!secondary_backend); + exit(1); + } + + cp->con = pool_open(fd); + cp->closetime = 0; + return cp; +} + +static POOL_CONNECTION_POOL *new_connection(POOL_CONNECTION_POOL *p) +{ + /* create master connection */ + MASTER_CONNECTION(p) = malloc(sizeof(POOL_CONNECTION_POOL_SLOT)); + if (MASTER_CONNECTION(p) == NULL) + { + pool_error("pool_create_cp: malloc() failed"); + return NULL; + } + create_cp(MASTER_CONNECTION(p), 0); + + /* initialize Paramter Status save structure */ + if (pool_init_params(&MASTER(p)->params)) + { + return NULL; + } + p->num = 1; /* number of slots */ + + /* create secondary connection */ + if (DUAL_MODE) + { + SECONDARY_CONNECTION(p) = malloc(sizeof(POOL_CONNECTION_POOL_SLOT)); + if (SECONDARY_CONNECTION(p) == NULL) + { + pool_error("pool_create_cp: malloc() failed"); + return NULL; + } + create_cp(SECONDARY_CONNECTION(p), 1); + + /* initialize Paramter Status save structure */ + if (pool_init_params(&MASTER(p)->params)) + { + return NULL; + } + + p->num++; /* number of slots */ + } + + return p; +} diff --git a/pool_error.c b/pool_error.c new file mode 100644 index 0000000..24fd295 --- /dev/null +++ b/pool_error.c @@ -0,0 +1,144 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_error.c: error and debug messages + * + */ + +#include +#include +#include +#include + +#include "pool.h" + +#define MAXSTRFTIME 128 + +extern int debug; + +static char *nowsec(void); + +void pool_error(const char *fmt,...) +{ + va_list ap; +#ifdef HAVE_ASPRINTF + char *fmt2; +#endif + + if (pool_config.print_timestamp) +#ifdef HAVE_ASPRINTF + asprintf(&fmt2, "%s ERROR: pid %d: %s\n", nowsec(), (int)getpid(), fmt); + else + asprintf(&fmt2, "ERROR: pid %d: %s\n", (int)getpid(), fmt); + + if (fmt2) + { + va_start(ap, fmt); + vfprintf(stderr, fmt2, ap); + va_end(ap); + fflush(stderr); + } +#else + fprintf(stderr, "%s ERROR: pid %d: ", nowsec(), (int)getpid()); + else + fprintf(stderr, "ERROR: pid %d: ", (int)getpid()); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +#endif +} + +void pool_debug(const char *fmt,...) +{ + va_list ap; +#ifdef HAVE_ASPRINTF + char *fmt2; +#endif + + if (!debug) + return; + + if (pool_config.print_timestamp) +#ifdef HAVE_ASPRINTF + asprintf(&fmt2, "%s DEBUG: pid %d: %s\n", nowsec(), (int)getpid(), fmt); + else + asprintf(&fmt2, "DEBUG: pid %d: %s\n", (int)getpid(), fmt); + + if (fmt2) + { + va_start(ap, fmt); + vfprintf(stderr, fmt2, ap); + va_end(ap); + fflush(stderr); + } +#else + fprintf(stderr, "%s DEBUG: pid %d: ", nowsec(), (int)getpid()); + else + fprintf(stderr, "DEBUG: pid %d: ", (int)getpid()); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +#endif +} + +void pool_log(const char *fmt,...) +{ + va_list ap; +#ifdef HAVE_ASPRINTF + char *fmt2; +#endif + + if (pool_config.print_timestamp) +#ifdef HAVE_ASPRINTF + asprintf(&fmt2, "%s LOG: pid %d: %s\n", nowsec(), (int)getpid(), fmt); + else + asprintf(&fmt2, "LOG: pid %d: %s\n", (int)getpid(), fmt); + + if (fmt2) + { + va_start(ap, fmt); + vfprintf(stderr, fmt2, ap); + va_end(ap); + fflush(stderr); + } +#else + fprintf(stderr, "%s LOG: pid %d: ", nowsec(), (int)getpid()); + else + fprintf(stderr, "LOG: pid %d: ", (int)getpid()); + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + fprintf(stderr, "\n"); +#endif +} + +static char *nowsec(void) +{ + static char strbuf[MAXSTRFTIME]; + time_t now = time(NULL); + + strftime(strbuf, MAXSTRFTIME, "%Y-%m-%d %H:%M:%S", localtime(&now)); + return strbuf; +} diff --git a/pool_params.c b/pool_params.c new file mode 100644 index 0000000..51ee857 --- /dev/null +++ b/pool_params.c @@ -0,0 +1,161 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * params.c: Paramter Status handling routines + * + */ +#include "config.h" + +#include +#include + +#include "pool.h" + +#define MAX_PARAM_ITEMS 128 + +/* + * initialize parameter structure + */ +int pool_init_params(ParamStatus *params) +{ + params->num = 0; + params->names = malloc(MAX_PARAM_ITEMS*sizeof(char *)); + if (params->names == NULL) + { + pool_error("pool_init_params: cannot allocate memory"); + return -1; + } + params->values = malloc(MAX_PARAM_ITEMS*sizeof(char *)); + if (params->values == NULL) + { + pool_error("pool_init_params: cannot allocate memory"); + return -1; + } + return 0; +} + +/* + * discard parameter structure + */ +void pool_discard_params(ParamStatus *params) +{ + int i; + + for (i=0;inum;i++) + { + free(params->names[i]); + free(params->values[i]); + } + free(params->names); + free(params->values); +} + +/* + * find param value by name. if found, its value is returned + * also, pos is set + * if not found, NULL is returned + */ +char *pool_find_name(ParamStatus *params, char *name, int *pos) +{ + int i; + + for (i=0;inum;i++) + { + if (!strcmp(name, params->names[i])) + { + *pos = i; + return params->values[i]; + } + } + return NULL; +} + +/* + * return name and value by index. + */ +int pool_get_param(ParamStatus *params, int index, char **name, char **value) +{ + if (index < 0 || index >= params->num) + return -1; + + *name = params->names[index]; + *value = params->values[index]; + + return 0; +} + +/* + * add or replace name/value pair + */ +int pool_add_param(ParamStatus *params, char *name, char *value) +{ + int pos; + + if (pool_find_name(params, name, &pos)) + { + /* name already exists */ + if (strlen(params->values[pos]) < strlen(value)) + { + params->values[pos] = realloc(params->values[pos], strlen(value) + 1); + if (params->values[pos] == NULL) + { + pool_error("pool_init_params: cannot allocate memory"); + return -1; + } + } + strcpy(params->values[pos], value); + } + else + { + int num; + + /* add name/value pair */ + if (params->num >= MAX_PARAM_ITEMS) + { + pool_error("pool_add_param: no more room for num"); + return -1; + } + num = params->num; + params->names[num] = strdup(name); + if (params->names[num] == NULL) + { + pool_error("pool_init_params: cannot allocate memory"); + return -1; + } + params->values[num] = strdup(value); + if (params->values[num] == NULL) + { + pool_error("pool_init_params: cannot allocate memory"); + return -1; + } + params->num++; + } + return 0; +} + +void pool_param_debug_print(ParamStatus *params) +{ + int i; + + for (i=0;inum;i++) + { + pool_debug("No.%d: name: %s value: %s", i, params->names[i], params->values[i]); + } +} diff --git a/pool_process_query.c b/pool_process_query.c new file mode 100644 index 0000000..a1b10c1 --- /dev/null +++ b/pool_process_query.c @@ -0,0 +1,2212 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Copyright (c) 2003-2005 Tatsuo Ishii + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool_process_query.c: query processing stuff + * +*/ +#include "config.h" +#include + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#ifdef HAVE_SYS_TIME_H +#include +#endif + +#include +#include +#include +#include + +#include "pool.h" + +static POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS Query(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, char *query); + +static POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int send_ready); + +static POOL_STATUS CompleteCommandResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int copyin); + +static POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS NoticeResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS EmptyQueryResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static int RowDescription(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS AsciiRow(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + short num_fields); + +static POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + short num_fields); + +static POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS FunctionResultResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static POOL_STATUS ProcessFrontendResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend); + +static int synchronize(POOL_CONNECTION *cp); +static void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend); +static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt); + +static int load_balance_enabled(POOL_CONNECTION_POOL *backend, char *sql); +static void start_load_balance(POOL_CONNECTION_POOL *backend); +static void end_load_balance(POOL_CONNECTION_POOL *backend); + +static POOL_CONNECTION_POOL_SLOT *slots[MAX_CONNECTION_SLOTS]; +static int in_load_balance; +static int master_slave_dml; +static int replication_was_enabled; +static int master_slave_was_enabled; + +POOL_STATUS pool_process_query(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + int connection_reuse) +{ + char kind, kind1; /* packet kind (backend) */ + char fkind; /* packet kind (frontend) */ + short num_fields = 0; + fd_set readmask; + fd_set writemask; + fd_set exceptmask; + int fds; + POOL_STATUS status; + int state; /* 0: ok to issue commands 1: waiting for "ready for query" response */ + int qcnt; + + frontend->no_forward = connection_reuse; + qcnt = 0; + state = 0; + + for (;;) + { + kind = kind1 = 0; + fkind = 0; + + if (state == 0 && connection_reuse) + { + int st; + + /* send query for resetting connection such as "ROLLBACK" "RESET ALL"... */ + st = reset_backend(backend, qcnt); + + if (st < 0) /* error? */ + { + /* probably we don't need this, since caller will + * close the connection to frontend after returning with POOL_END. But I + * guess I would like to be a paranoid... + */ + frontend->no_forward = 0; + return POOL_END; + } + + else if (st == 0) /* no query issued? */ + { + qcnt++; + continue; + } + + else if (st == 1) /* more query remains */ + { + state = 1; + qcnt++; + continue; + } + + else /* no more query(st == 2) */ + { + frontend->no_forward = 0; + return POOL_CONTINUE; + } + + } + + if ((!DUAL_MODE && MASTER(backend)->len == 0 && frontend->len == 0) || + (DUAL_MODE && MASTER(backend)->len == 0 && + SECONDARY(backend)->len == 0 + && frontend->len == 0)) + { + + struct timeval timeout; + + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + FD_ZERO(&readmask); + FD_ZERO(&writemask); + FD_ZERO(&exceptmask); + if (!connection_reuse) + FD_SET(frontend->fd, &readmask); + FD_SET(MASTER(backend)->fd, &readmask); + if (DUAL_MODE) + FD_SET(SECONDARY(backend)->fd, &readmask); + if (!connection_reuse) + FD_SET(frontend->fd, &exceptmask); + FD_SET(MASTER(backend)->fd, &exceptmask); + + if (connection_reuse) + { + if (DUAL_MODE) + fds = select(Max(SECONDARY(backend)->fd, MASTER(backend)->fd) + 1, + &readmask, &writemask, &exceptmask, NULL); + else + fds = select(MASTER(backend)->fd+1, &readmask, &writemask, &exceptmask, NULL); + } + else + { + if (DUAL_MODE) + fds = select(Max(SECONDARY(backend)->fd, + Max(frontend->fd, MASTER(backend)->fd)+1), + &readmask, &writemask, &exceptmask, NULL); + else + fds = select(Max(frontend->fd, MASTER(backend)->fd)+1, + &readmask, &writemask, &exceptmask, NULL); + } + + if (fds == -1) + { + if (errno == EINTR) + continue; + + pool_error("select() failed. reason: %s", strerror(errno)); + return POOL_ERROR; + } + + if (fds == 0) + { + return POOL_CONTINUE; + } + + if (FD_ISSET(MASTER(backend)->fd, &readmask)) + { + pool_read(MASTER(backend), &kind, 1); + pool_debug("read kind from backend %c", kind); + } + + if (DUAL_MODE && FD_ISSET(SECONDARY(backend)->fd, &readmask)) + { + pool_read(SECONDARY(backend), &kind1, 1); + pool_debug("read kind from secondary backend %c", kind1); + } + + if (!connection_reuse && FD_ISSET(frontend->fd, &exceptmask)) + { + return POOL_END; + } + if (FD_ISSET(MASTER(backend)->fd, &exceptmask)) + { + return POOL_ERROR; + } + + if (!connection_reuse && FD_ISSET(frontend->fd, &readmask)) + { + status = ProcessFrontendResponse(frontend, backend); + if (status != POOL_CONTINUE) + return status; + + continue; + } + } + else + { + if (MASTER(backend)->len > 0) + { + pool_read(MASTER(backend), &kind, 1); + if (DUAL_MODE) + { + pool_read(SECONDARY(backend), &kind1, 1); + if (kind == '\0' || kind != kind1) + { + int sts; + + pool_error("pool_process_query: kind does not match between backends master(%c) secondary(%c)", + kind, kind1); + pool_send_error_message(frontend, MAJOR(backend), "XX000", + "kind mismatch between backends", "", + "check data consistency between master and secondary", __FILE__, __LINE__); + + /* health check */ + sts = health_check(); + if (sts == -1) + { + notice_backend_error(1); + exit(1); + } + else if (sts == -2) + { + notice_backend_error(0); + exit(1); + } + + if (pool_config.replication_stop_on_mismatch) + return POOL_FATAL; + else + return POOL_ERROR; + } + } + pool_debug("read kind from backend pending data %c len: %d po: %d", kind, MASTER(backend)->len, MASTER(backend)->po); + } + if (frontend->len > 0) + { + status = ProcessFrontendResponse(frontend, backend); + if (status != POOL_CONTINUE) + return status; + + continue; + } + } + + /* this is the synchronous point */ + if (DUAL_MODE) + { + if (kind == 0) + { + pool_read(MASTER(backend), &kind, 1); + } + if (kind1 == 0) + { + if (SECONDARY(backend)->len <= 0) + { + /* at this point the query should have completed and it's safe to set timeout here */ + pool_debug("pool_process_query: waiting for secondary for data ready"); + + /* temporary enable timeout */ + pool_enable_timeout(); + + if (pool_check_fd(SECONDARY(backend), 0)) + { + pool_error("pool_process_query: secondary data is not ready at synchronous point. abort this session"); + + } + else + { + pool_read(SECONDARY(backend), &kind1, 1); + } + + pool_disable_timeout(); + } + else + { + pool_read(SECONDARY(backend), &kind1, 1); + } + } + + if (kind == '\0' || kind != kind1) + { + int sts; + + pool_error("pool_process_query: kind does not match between backends master(%c) secondary(%c)", + kind, kind1); + pool_send_error_message(frontend, MAJOR(backend), "XX000", + "kind mismatch between backends", "", + "check data consistency between master and secondary", __FILE__, __LINE__); + + /* health check */ + sts = health_check(); + if (sts == -1) + { + notice_backend_error(1); + exit(1); + } + else if (sts == -2) + { + notice_backend_error(0); + exit(1); + } + + if (pool_config.replication_stop_on_mismatch) + return POOL_FATAL; + else + return POOL_ERROR; + } + } + + /* + * Prrocess backend Response + */ + + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + switch (kind) + { + case 'G': + /* CopyIn response */ + status = CopyInResponse(frontend, backend); + break; + case 'S': + /* Paramter Status */ + status = ParameterStatus(frontend, backend); + break; + case 'Z': + /* Ready for query */ + status = ReadyForQuery(frontend, backend, 1); + break; + default: + status = SimpleForwardToFrontend(kind, frontend, backend); + break; + } + } + else + { + switch (kind) + { + case 'A': + /* Notification response */ + status = NotificationResponse(frontend, backend); + break; + + case 'B': + /* BinaryRow */ + status = BinaryRow(frontend, backend, num_fields); + break; + + case 'C': + /* Complete command response */ + status = CompleteCommandResponse(frontend, backend); + break; + + case 'D': + /* AsciiRow */ + status = AsciiRow(frontend, backend, num_fields); + break; + + case 'E': + /* Error Response */ + status = ErrorResponse(frontend, backend); + break; + + case 'G': + /* CopyIn Response */ + status = CopyInResponse(frontend, backend); + break; + + case 'H': + /* CopyOut Response */ + status = CopyOutResponse(frontend, backend); + break; + + case 'I': + /* Empty Query Response */ + status = EmptyQueryResponse(frontend, backend); + break; + + case 'N': + /* Notice Response */ + status = NoticeResponse(frontend, backend); + break; + + case 'P': + /* CursorResponse */ + status = CursorResponse(frontend, backend); + break; + + case 'T': + /* RowDescription */ + status = RowDescription(frontend, backend); + if (status < 0) + return POOL_ERROR; + + num_fields = status; + status = POOL_CONTINUE; + break; + + case 'V': + /* FunctionResultResponse and FunctionVoidResponse */ + status = FunctionResultResponse(frontend, backend); + break; + + case 'Z': + /* Ready for query */ + status = ReadyForQuery(frontend, backend, 1); + break; + + default: + pool_error("Unknown message type %c(%02x)", kind, kind); + exit(1); + } + } + + if (status != POOL_CONTINUE) + return status; + + if (kind == 'Z' && frontend->no_forward && state == 1) + { + state = 0; + } + + } + return POOL_CONTINUE; +} + +static POOL_STATUS Query(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, char *query) +{ + char *string; + int len; + static char *sq = "show pool_status"; + + if (query == NULL) + { + /* read actual query */ + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + if (pool_read(frontend, &len, sizeof(len)) < 0) + return POOL_END; + len = ntohl(len) - 4; + string = pool_read2(frontend, len); + } + else + string = pool_read_string(frontend, &len, 0); + + if (string == NULL) + return POOL_END; + } + else + { + len = strlen(query)+1; + string = query; + } + + pool_debug("Query: %s", string); + + /* process status reporting? */ + if (strncasecmp(sq, string, strlen(sq)) == 0) + { + pool_debug("process reporting"); + process_reporting(frontend, backend); + return POOL_CONTINUE; + } + + /* load balance trick */ + if (load_balance_enabled(backend, string)) + start_load_balance(backend); + else if (MASTER_SLAVE) + { + master_slave_was_enabled = 1; + MASTER_SLAVE = 0; + master_slave_dml = 1; + } + + /* forward the query to the backend */ + pool_write(MASTER(backend), "Q", 1); + + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + int sendlen = htonl(len + 4); + pool_write(MASTER(backend), &sendlen, sizeof(sendlen)); + } + + if (pool_write_and_flush(MASTER(backend), string, len) < 0) + { + return POOL_END; + } + + if (REPLICATION) + { + /* in "strict mode" we need to wait for master completing the query */ + if (pool_config.replication_strict || STRICT_MODE(string)) + if (synchronize(MASTER(backend))) + return POOL_END; + +#define SEQUENCE_DEBUG +#ifdef SEQUENCE_DEBUG + if (!strncmp(string, "/*SLEEP*/", 9)) + { + pool_debug("start sleeping"); + sleep(20); + pool_debug("end sleeping"); + } +#endif + + pool_write(SECONDARY(backend), "Q", 1); + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + int sendlen = htonl(len + 4); + pool_write(SECONDARY(backend), &sendlen, sizeof(sendlen)); + } + + if (pool_write_and_flush(SECONDARY(backend), string, len) < 0) + { + return POOL_END; + } + + /* in "strict mode" we need to wait for secondary completing the query */ + if (pool_config.replication_strict || STRICT_MODE(string)) + if (synchronize(SECONDARY(backend))) + return POOL_END; + } + return POOL_CONTINUE; +} + +static POOL_STATUS ReadyForQuery(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int send_ready) +{ + pool_flush(frontend); + + if (send_ready) + { + pool_write(frontend, "Z", 1); + + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + int len; + signed char state; + + if ((len = pool_read_message_length(backend)) < 0) + return POOL_END; + + pool_debug("ReadyForQuery: message length: %d", len); + + len = htonl(len); + pool_write(frontend, &len, sizeof(len)); + + state = pool_read_kind(backend); + if (state < 0) + return POOL_END; + + /* set transaction state */ + pool_debug("ReadyForQuery: transaction state: %c", state); + MASTER(backend)->tstate = state; + if (REPLICATION) + SECONDARY(backend)->tstate = state; + + pool_write(frontend, &state, 1); + } + + if (pool_flush(frontend)) + return POOL_END; + } + + /* end load balance mode */ + if (in_load_balance) + end_load_balance(backend); + + if (master_slave_dml) + { + MASTER_SLAVE = 1; + master_slave_was_enabled = 0; + master_slave_dml = 0; + } + + return ProcessFrontendResponse(frontend, backend); +} + +static POOL_STATUS CompleteCommandResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char *string, *string1; + int len, len1; + + /* read command tag */ + string = pool_read_string(MASTER(backend), &len, 0); + if (string == NULL) + return POOL_END; + + if (REPLICATION) + { + string1 = pool_read_string(SECONDARY(backend), &len1, 0); + if (string1 == NULL) + return POOL_END; + + if (len != len1) + { + pool_log("Complete Command Response: message length does not match between master(%d \"%s\",) and secondary(%d \"%s\",)", + len, string, len1, string1); + } + } + + /* forward to the frontend */ + pool_write(frontend, "C", 1); + pool_debug("Complete Command Response: string: \"%s\"", string); + if (pool_write(frontend, string, len) < 0) + { + return POOL_END; + } + return POOL_CONTINUE; +} + +static int RowDescription(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + short num_fields, num_fields1; + int oid, mod; + int oid1, mod1; + short size, size1; + char *string, *string1; + int len, len1; + int i; + + /* # of fields (could be 0) */ + pool_read(MASTER(backend), &num_fields, sizeof(short)); + if (REPLICATION) + { + pool_read(SECONDARY(backend), &num_fields1, sizeof(short)); + if (num_fields != num_fields1) + { + pool_error("RowDescription: num_fields deos not match between backends master(%d) and secondary(%d)", + num_fields, num_fields1); + return POOL_FATAL; + } + } + + /* forward it to the frontend */ + pool_write(frontend, "T", 1); + pool_write(frontend, &num_fields, sizeof(short)); + + num_fields = ntohs(num_fields); + for (i = 0;i 0 */ + if (size > 0) + { + buf = pool_read2(MASTER(backend), size); + if (buf == NULL) + return POOL_END; + } + } + + if (REPLICATION && size1 > 0 && (mask & nullmap1[i/8])) + { + /* read and discard secondary data */ + if (pool_read2(SECONDARY(backend), size1) == NULL) + return POOL_END; + } + + if (buf) + { + pool_write(frontend, buf, size); + snprintf(msgbuf, Min(sizeof(msgbuf), size+1), "%s", buf); + pool_debug("AsciiRow: len: %d data: %s", size, msgbuf); + } + + mask >>= 1; + } + + return POOL_CONTINUE; +} + +static POOL_STATUS BinaryRow(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, + short num_fields) +{ + static char nullmap[8192], nullmap1[8192]; + int nbytes; + int i; + unsigned char mask; + int size, size1; + char *buf; + + pool_write(frontend, "B", 1); + + nbytes = (num_fields + 7)/8; + + if (nbytes <= 0) + return POOL_CONTINUE; + + /* NULL map */ + pool_read(MASTER(backend), nullmap, nbytes); + if (pool_write(frontend, nullmap, nbytes) < 0) + return POOL_END; + + if (REPLICATION) + { + if (pool_read(SECONDARY(backend), nullmap1, nbytes) < 0) + return POOL_END; + + if (memcmp(nullmap, nullmap1, nbytes)) + { + /* XXX: NULLMAP maybe different among + backends. If we were a paranoid, we have to treat + this as a fatal error. However in the real world + we'd better to adapt this situation. Just throw a + log... */ + pool_log("BinaryRow: NULLMAP differ between master and secondary"); + } + } + + mask = 0; + + for (i = 0;i 0 */ + if (size > 0) + { + buf = pool_read2(MASTER(backend), size); + if (buf == NULL) + return POOL_END; + } + } + + if (REPLICATION && size1 > 0 && (mask & nullmap1[i/8])) + { + /* read and discard secondary data */ + if (pool_read2(SECONDARY(backend), size1) == NULL) + return POOL_END; + } + + if (buf) + pool_write(frontend, buf, size); + + mask >>= 1; + } + return POOL_CONTINUE; +} + +static POOL_STATUS CursorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char *string, *string1; + int len, len1; + + /* read cursor name */ + string = pool_read_string(MASTER(backend), &len, 0); + if (string == NULL) + return POOL_END; + if (REPLICATION) + { + string1 = pool_read_string(SECONDARY(backend), &len1, 0); + if (string1 == NULL) + return POOL_END; + if (len != len1) + { + pool_error("CursorResponse: length does not match between master(%d) and secondary(%d)", + len, len1); + pool_error("CursorResponse: master(%s) secondary(%s)", string, string1); + return POOL_END; + } + } + + /* forward to the frontend */ + pool_write(frontend, "P", 1); + if (pool_write(frontend, string, len) < 0) + { + return POOL_END; + } + return POOL_CONTINUE; +} + +POOL_STATUS ErrorResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char *string; + int len; + + /* read error message */ + string = pool_read_string(MASTER(backend), &len, 0); + if (string == NULL) + return POOL_END; + if (REPLICATION) + { + string = pool_read_string(SECONDARY(backend), &len, 0); + if (string == NULL) + return POOL_END; + } + + /* forward to the frontend */ + pool_write(frontend, "E", 1); + if (pool_write_and_flush(frontend, string, len) < 0) + return POOL_END; + + return POOL_CONTINUE; +} + +static POOL_STATUS NoticeResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char *string, *string1; + int len, len1; + + /* read notice message */ + string = pool_read_string(MASTER(backend), &len, 0); + if (string == NULL) + return POOL_END; + if (REPLICATION) + { + string1 = pool_read_string(SECONDARY(backend), &len1, 0); + if (string1 == NULL) + return POOL_END; + } + + /* forward to the frontend */ + pool_write(frontend, "N", 1); + if (pool_write_and_flush(frontend, string, len) < 0) + { + return POOL_END; + } + return POOL_CONTINUE; +} + +static POOL_STATUS CopyInResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + POOL_STATUS status; + + /* forward to the frontend */ + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + if (SimpleForwardToFrontend('G', frontend, backend) != POOL_CONTINUE) + return POOL_END; + if (pool_flush(frontend) != POOL_CONTINUE) + return POOL_END; + } + else + if (pool_write_and_flush(frontend, "G", 1) < 0) + return POOL_END; + + status = CopyDataRows(frontend, backend, 1); + return status; +} + +static POOL_STATUS CopyOutResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + POOL_STATUS status; + + /* forward to the frontend */ + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + if (SimpleForwardToFrontend('H', frontend, backend) != POOL_CONTINUE) + return POOL_END; + if (pool_flush(frontend) != POOL_CONTINUE) + return POOL_END; + } + else + if (pool_write_and_flush(frontend, "H", 1) < 0) + return POOL_END; + + status = CopyDataRows(frontend, backend, 0); + return status; +} + +static POOL_STATUS CopyDataRows(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend, int copyin) +{ + char *string; + int len; + +#ifdef DEBUG + int i = 0; + char buf[1024]; +#endif + + for (;;) + { + if (copyin) + { + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + char kind; + + if (pool_read(frontend, &kind, 1) < 0) + return POOL_END; + + SimpleForwardToBackend(kind, frontend, backend); + + /* CopyData? */ + if (kind == 'd') + continue; + else + break; + } + else + string = pool_read_string(frontend, &len, 1); + } + else + { + /* CopyOut */ + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + signed char kind; + + if ((kind = pool_read_kind(backend)) < 0) + return POOL_END; + + SimpleForwardToFrontend(kind, frontend, backend); + + /* CopyData? */ + if (kind == 'd') + continue; + else + break; + } + else + { + string = pool_read_string(MASTER(backend), &len, 1); + if (REPLICATION) + string = pool_read_string(SECONDARY(backend), &len, 1); + } + } + + if (string == NULL) + return POOL_END; + +#ifdef DEBUG + strncpy(buf, string, len); + pool_debug("copy line %d %d bytes :%s:", i++, len, buf); +#endif + + if (copyin) + { + pool_write(MASTER(backend), string, len); + if (REPLICATION) + pool_write(SECONDARY(backend), string, len); + } + else + pool_write(frontend, string, len); + + if (len == PROTO_MAJOR_V3) + { + /* end of copy? */ + if (string[0] == '\\' && + string[1] == '.' && + string[2] == '\n') + { + break; + } + } + } + + if (copyin) + { + if (pool_flush(MASTER(backend)) <0) + return POOL_END; + if (REPLICATION) + { + if (pool_flush(SECONDARY(backend)) <0) + return POOL_END; + } + } + else + if (pool_flush(frontend) <0) + return POOL_END; + + return POOL_CONTINUE; +} + +static POOL_STATUS EmptyQueryResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char c; + + if (pool_read(MASTER(backend), &c, sizeof(c)) < 0) + return POOL_END; + + if (REPLICATION) + { + if (pool_read(SECONDARY(backend), &c, sizeof(c)) < 0) + return POOL_END; + } + + pool_write(frontend, "I", 1); + return pool_write_and_flush(frontend, "", 1); +} + +static POOL_STATUS NotificationResponse(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + int pid, pid1; + char *condition, *condition1; + int len, len1; + + pool_write(frontend, "A", 1); + + if (pool_read(MASTER(backend), &pid, sizeof(pid)) < 0) + return POOL_ERROR; + + if (REPLICATION) + { + if (pool_read(SECONDARY(backend), &pid1, sizeof(pid1)) < 0) + return POOL_ERROR; + } + + condition = pool_read_string(MASTER(backend), &len, 0); + if (condition == NULL) + return POOL_END; + if (REPLICATION) + { + condition1 = pool_read_string(SECONDARY(backend), &len1, 0); + if (condition1 == NULL) + return POOL_END; + } + + pool_write(frontend, &pid, sizeof(pid)); + + return pool_write_and_flush(frontend, condition, len); +} + +static POOL_STATUS FunctionCall(POOL_CONNECTION *frontend, + POOL_CONNECTION_POOL *backend) +{ + char dummy[2]; + int oid; + int argn; + int i; + + pool_write(MASTER(backend), "F", 1); + if (REPLICATION) + pool_write(SECONDARY(backend), "F", 1); + + /* dummy */ + if (pool_read(frontend, dummy, sizeof(dummy)) < 0) + return POOL_ERROR; + pool_write(MASTER(backend), dummy, sizeof(dummy)); + if (REPLICATION) + pool_write(SECONDARY(backend), dummy, sizeof(dummy)); + + /* function object id */ + if (pool_read(frontend, &oid, sizeof(oid)) < 0) + return POOL_ERROR; + + pool_write(MASTER(backend), &oid, sizeof(oid)); + if (REPLICATION) + pool_write(SECONDARY(backend), &oid, sizeof(oid)); + + /* number of arguments */ + if (pool_read(frontend, &argn, sizeof(argn)) < 0) + return POOL_ERROR; + pool_write(MASTER(backend), &argn, sizeof(argn)); + if (REPLICATION) + pool_write(SECONDARY(backend), &argn, sizeof(argn)); + + argn = ntohl(argn); + + for (i=0;ilen <= 0 && frontend->no_forward != 0) + return POOL_CONTINUE; + + if (pool_read(frontend, &fkind, 1) < 0) + { + pool_error("ProcessFrontendResponse: failed to read kind"); + return POOL_END; + } + + pool_debug("read kind from frontend %c(%02x)", fkind, fkind); + + switch (fkind) + { + case 'X': + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + int len; + pool_read(frontend, &len, sizeof(len)); + } + status = POOL_END; + break; + + case 'Q': + status = Query(frontend, backend, NULL); + break; + + default: + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + status = SimpleForwardToBackend(fkind, frontend, backend); + if (pool_flush(MASTER(backend))) + status = POOL_ERROR; + if (REPLICATION) + if (pool_flush(SECONDARY(backend))) + status = POOL_ERROR; + } + else if (MAJOR(backend) == PROTO_MAJOR_V2 && fkind == 'F') + status = FunctionCall(frontend, backend); + else + { + pool_error("ProcessFrontendResponse: unknown message type %c(%02x)", fkind, fkind); + status = POOL_ERROR; + } + break; + } + + return status; +} + +static int timeoutmsec; + +/* + * enable read timeout + */ +void pool_enable_timeout() +{ + timeoutmsec = pool_config.replication_timeout; +} + +/* + * disable read timeout + */ +void pool_disable_timeout() +{ + timeoutmsec = 0; +} + +/* + * wait until read data is ready + */ +static int synchronize(POOL_CONNECTION *cp) +{ + return pool_check_fd(cp, 1); +} + +/* + * wait until read data is ready + * if notimeout is non 0, wait forever. + */ +int pool_check_fd(POOL_CONNECTION *cp, int notimeout) +{ + fd_set readmask; + fd_set exceptmask; + int fd; + int fds; + struct timeval timeout; + struct timeval *tp; + + fd = cp->fd; + + for (;;) + { + FD_ZERO(&readmask); + FD_ZERO(&exceptmask); + FD_SET(fd, &readmask); + FD_SET(fd, &exceptmask); + + if (notimeout || timeoutmsec == 0) + tp = NULL; + else + { + timeout.tv_sec = pool_config.replication_timeout / 1000; + timeout.tv_usec = (pool_config.replication_timeout - (timeout.tv_sec * 1000))*1000; + tp = &timeout; + } + + fds = select(fd+1, &readmask, NULL, &exceptmask, tp); + + if (fds == -1) + { + if (errno == EAGAIN || errno == EINTR) + continue; + + pool_error("pool_check_fd: select() failed. reason %s", strerror(errno)); + break; + } + + if (FD_ISSET(fd, &exceptmask)) + { + pool_error("pool_check_fd: exception occurred"); + break; + } + + if (fds == 0) + { + pool_error("pool_check_fd: data is not ready tp->tv_sec %d tp->tp_usec %d", + pool_config.replication_timeout / 1000, + (pool_config.replication_timeout - (timeout.tv_sec * 1000))*1000); + break; + } + return 0; + } + return -1; +} + +static void process_reporting(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +{ + static char *cursorname = "blank"; + static short num_fields = 3; + static char *field_names[] = {"item", "value", "description"}; + static int oid = 0; + static short fsize = -1; + static int mod = 0; + short n; + int i, j; + short s; + int len; + short colnum; + + static char nullmap[2] = {0xff, 0xff}; + int nbytes = (num_fields + 7)/8; + +#define MAXVALLEN 512 + + typedef struct { + char *name; + char value[MAXVALLEN+1]; + char *desc; + } POOL_REPORT_STATUS; + +#define MAXITEMS 128 + + POOL_REPORT_STATUS status[MAXITEMS]; + + short nrows; + int size; + int hsize; + + i = 0; + + status[i].name = "listen_addresses"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.listen_addresses); + status[i].desc = "host name(s) or IP address(es) to listen to"; + i++; + + status[i].name = "port"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.port); + status[i].desc = "pgpool accepting port number"; + i++; + + status[i].name = "socket_dir"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.socket_dir); + status[i].desc = "pgpool socket directory"; + i++; + + status[i].name = "backend_host_name"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.backend_host_name); + status[i].desc = "master backend host name"; + i++; + + status[i].name = "backend_port"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.backend_port); + status[i].desc = "master backend port number"; + i++; + + status[i].name = "secondary_backend_host_name"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.secondary_backend_host_name); + status[i].desc = "secondary backend host name"; + i++; + + status[i].name = "secondary_backend_port"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.secondary_backend_port); + status[i].desc = "secondary backend port number"; + i++; + + status[i].name = "num_init_children"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.num_init_children); + status[i].desc = "# of children initially pre-forked"; + i++; + + status[i].name = "child_life_time"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.child_life_time); + status[i].desc = "if idle for this seconds, child exits"; + i++; + + status[i].name = "connection_life_time"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.connection_life_time); + status[i].desc = "if idle for this seconds, connection closes"; + i++; + + status[i].name = "max_pool"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.max_pool); + status[i].desc = "max # of connection pool per child"; + i++; + + status[i].name = "logdir"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.logdir); + status[i].desc = "logging directory"; + i++; + + status[i].name = "backend_socket_dir"; + snprintf(status[i].value, MAXVALLEN, "%s", pool_config.backend_socket_dir); + status[i].desc = "Unix domain socket directory for the PostgreSQL server"; + i++; + + status[i].name = "replication_mode"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.replication_mode); + status[i].desc = "non 0 if operating in replication mode"; + i++; + + status[i].name = "replication_strict"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.replication_strict); + status[i].desc = "non 0 if operating in strict mode"; + i++; + + status[i].name = "replication_timeout"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.replication_timeout); + status[i].desc = "if secondary does not respond in this milli seconds, abort the session"; + i++; + + status[i].name = "load_balance_mode"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.load_balance_mode); + status[i].desc = "non 0 if operating in load balancing mode"; + i++; + + status[i].name = "weight_master"; + snprintf(status[i].value, MAXVALLEN, "%f", pool_config.weight_master); + status[i].desc = "weight of master"; + i++; + + status[i].name = "weight_secondary"; + snprintf(status[i].value, MAXVALLEN, "%f", pool_config.weight_secondary); + status[i].desc = "weight of secondary"; + i++; + + status[i].name = "replication_stop_on_mismatch"; + snprintf(status[i].value, MAXVALLEN, "%d", pool_config.replication_stop_on_mismatch); + status[i].desc = "stop replication mode on fatal error"; + i++; + + status[i].name = "reset_query_list"; + *(status[i].value) = '\0'; + for (j=0;jwrite_fd); + + if (DUAL_MODE) + { + pool_write(SECONDARY(backend), "X", 1); + if (MAJOR(backend) == PROTO_MAJOR_V3) + { + len = htonl(4); + pool_write(SECONDARY(backend), &len, sizeof(len)); + } + fflush(SECONDARY(backend)->write_fd); + } +} + +/* + * ------------------------------------------------------- + * V3 functions + * ------------------------------------------------------- + */ +POOL_STATUS SimpleForwardToFrontend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +{ + int len, len1; + char *p; + int status; + + pool_write(frontend, &kind, 1); + + status = pool_read(MASTER(backend), &len, sizeof(len)); + if (status < 0) + { + pool_error("SimpleForwardToFrontend: error while reading message length"); + return POOL_END; + } + + if (REPLICATION) + { + status = pool_read(SECONDARY(backend), &len1, sizeof(len1)); + if (status < 0) + { + pool_error("SimpleForwardToFrontend: error while reading message length from secondary backend"); + return POOL_END; + } + + if (len != len1) + { + pool_log("SimpleForwardToFrontend: length does not match between backends master(%d) secondary(%d) kind:(%c)", + ntohl(len), ntohl(len1), kind); + } + } + + pool_write(frontend, &len, sizeof(len)); + + len = ntohl(len); + len -= 4; + + p = pool_read2(MASTER(backend), len); + if (p == NULL) + return POOL_END; + + if (REPLICATION) + { + len1 = ntohl(len1); + len1 -= 4; + if (pool_read2(SECONDARY(backend), len1) == NULL) + return POOL_END; + } + + return pool_write(frontend, p, len); +} + +POOL_STATUS SimpleForwardToBackend(char kind, POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +{ + int len; + int sendlen; + char *p; + + if (pool_write(MASTER(backend), &kind, 1)) + return POOL_END; + if (REPLICATION) + if (pool_write(SECONDARY(backend), &kind, 1)) + return POOL_END; + + if (pool_read(frontend, &sendlen, sizeof(sendlen))) + { + return POOL_END; + } + + len = ntohl(sendlen) - 4; + + p = pool_read2(frontend, len); + if (p == NULL) + return POOL_END; + + if (pool_write(MASTER(backend), &sendlen, sizeof(sendlen))) + return POOL_END; + if (pool_write(MASTER(backend), p, len)) + return POOL_END; + + if (REPLICATION) + { + if (pool_write(SECONDARY(backend), &sendlen, sizeof(sendlen))) + return POOL_END; + if (pool_write(SECONDARY(backend), p, len)) + return POOL_END; + } + + return POOL_CONTINUE; +} + +POOL_STATUS ParameterStatus(POOL_CONNECTION *frontend, POOL_CONNECTION_POOL *backend) +{ + int len; + int sendlen; + char *p; + char *name; + char *value; + + pool_write(frontend, "S", 1); + + len = pool_read_message_length(backend); + if (len < 0) + { + return POOL_END; + } + + sendlen = htonl(len); + pool_write(frontend, &sendlen, sizeof(sendlen)); + + len -= 4; + + p = pool_read2(MASTER(backend), len); + if (p == NULL) + return POOL_END; + + name = p; + value = p + strlen(name) + 1; + + pool_debug("name: %s value: %s", name, value); + + pool_add_param(&MASTER(backend)->params, name, value); + +#ifdef DEBUG + pool_param_debug_print(&MASTER(backend)->params); +#endif + + if (DUAL_MODE) + if (pool_read2(SECONDARY(backend), len) == NULL) + return POOL_END; + + return pool_write(frontend, p, len); + +} + +/* + * reset backend status. return values are: + * 0: no query was issued 1: a query was issued 2: no more queries remain -1: error + */ +static int reset_backend(POOL_CONNECTION_POOL *backend, int qcnt) +{ + char *query; + int qn; + + qn = pool_config.num_reset_queries; + + if (qcnt >= qn) + return 2; + + query = pool_config.reset_query_list[qcnt]; + + /* if transaction state is idle, we don't need to issue ABORT */ + if (TSTATE(backend) == 'I' && !strcmp("ABORT", query)) + return 0; + + if (Query(NULL, backend, query) != POOL_CONTINUE) + return -1; + + return 1; +} + +/* + * return non 0 if load balance is possible + */ +static int load_balance_enabled(POOL_CONNECTION_POOL *backend, char *sql) +{ + if (pool_config.load_balance_mode && + DUAL_MODE && + MAJOR(backend) == PROTO_MAJOR_V3 && + TSTATE(backend) == 'I' && + !strncasecmp(sql, "SELECT", 6)) + return 1; + return 0; +} + +/* + * start load balance mode + */ +static void start_load_balance(POOL_CONNECTION_POOL *backend) +{ + int i; + int master; + + /* save backend connection slots */ + for (i=0;inum;i++) + { + slots[i] = backend->slots[i]; + } + + /* temporarily turn off replication mode */ + if (REPLICATION) + replication_was_enabled = 1; + if (MASTER_SLAVE) + master_slave_was_enabled = 1; + + REPLICATION = 0; + MASTER_SLAVE = 0; + + /* choose a master in random manner with weight */ + master = (random() <= weight_master)?0:1; + backend->slots[0] = slots[master]; + pool_debug("start_load_balance: selected master is %d", master); + + /* start load balancing */ + in_load_balance = 1; +} + +/* + * finish load balance mode + */ +static void end_load_balance(POOL_CONNECTION_POOL *backend) +{ + int i; + + /* restore backend connection slots */ + for (i=0;inum;i++) + { + backend->slots[i] = slots[i]; + } + + /* turn on replication mode */ + REPLICATION = replication_was_enabled; + MASTER_SLAVE = master_slave_was_enabled; + + replication_was_enabled = 0; + master_slave_was_enabled = 0; + in_load_balance = 0; + + pool_debug("end_load_balance: end load balance mode"); +} + +/* + * send error message to frontend + */ +void pool_send_error_message(POOL_CONNECTION *frontend, int protoMajor, + char *code, + char *message, + char *detail, + char *hint, + char *file, + int line) +{ +#define MAXDATA 1024 +#define MAXMSGBUF 128 + if (protoMajor == PROTO_MAJOR_V2) + { + pool_write(frontend, "E", 1); + pool_write_and_flush(frontend, message, strlen(message)+1); + } + else if (protoMajor == PROTO_MAJOR_V3) + { + char data[MAXDATA]; + char msgbuf[MAXMSGBUF]; + int len; + int thislen; + int sendlen; + + len = 0; + + pool_write(frontend, "E", 1); + + /* error level */ + thislen = snprintf(msgbuf, MAXMSGBUF, "SERROR"); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + + /* code */ + thislen = snprintf(msgbuf, MAXMSGBUF, "C%s", code); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + + /* message */ + thislen = snprintf(msgbuf, MAXMSGBUF, "M%s", message); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + + /* detail */ + if (*detail != '\0') + { + thislen = snprintf(msgbuf, MAXMSGBUF, "D%s", detail); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + } + + /* hint */ + if (*hint != '\0') + { + thislen = snprintf(msgbuf, MAXMSGBUF, "H%s", hint); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + } + + /* file */ + thislen = snprintf(msgbuf, MAXMSGBUF, "F%s", file); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + + /* line */ + thislen = snprintf(msgbuf, MAXMSGBUF, "L%d", line); + memcpy(data +len, msgbuf, thislen+1); + len += thislen + 1; + + /* stop null */ + len++; + *(data + len) = '\0'; + + sendlen = len; + len = htonl(len + 4); + pool_write(frontend, &len, sizeof(len)); + pool_write_and_flush(frontend, data, sendlen); + } + else + pool_error("send_error_message: unknown protocol major %d", protoMajor); +} diff --git a/pool_signal.c b/pool_signal.c new file mode 100644 index 0000000..f2b1d35 --- /dev/null +++ b/pool_signal.c @@ -0,0 +1,158 @@ +/* -*-pgsql-c-*- */ +/* + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Portions Copyright (c) 2003-2005, Tatsuo Ishii + * Portions Copyright (c) 2003-2004, PostgreSQL Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + */ + +/* + * Signal stuff. Stolen from PostgreSQL source code. + */ + +#include "config.h" +#include "pool_signal.h" +#include + +#ifdef HAVE_SIGPROCMASK +sigset_t UnBlockSig, + BlockSig, + AuthBlockSig; + +#else +int UnBlockSig, + BlockSig, + AuthBlockSig; +#endif + +/* + * Initialize BlockSig, UnBlockSig, and AuthBlockSig. + * + * BlockSig is the set of signals to block when we are trying to block + * signals. This includes all signals we normally expect to get, but NOT + * signals that should never be turned off. + * + * AuthBlockSig is the set of signals to block during authentication; + * it's essentially BlockSig minus SIGTERM, SIGQUIT, SIGALRM. + * + * UnBlockSig is the set of signals to block when we don't want to block + * signals (is this ever nonzero??) + */ +void +poolinitmask(void) +{ +#ifdef HAVE_SIGPROCMASK + sigemptyset(&UnBlockSig); + sigfillset(&BlockSig); + sigfillset(&AuthBlockSig); + + /* + * Unmark those signals that should never be blocked. Some of these + * signal names don't exist on all platforms. Most do, but might as + * well ifdef them all for consistency... + */ +#ifdef SIGTRAP + sigdelset(&BlockSig, SIGTRAP); + sigdelset(&AuthBlockSig, SIGTRAP); +#endif +#ifdef SIGABRT + sigdelset(&BlockSig, SIGABRT); + sigdelset(&AuthBlockSig, SIGABRT); +#endif +#ifdef SIGILL + sigdelset(&BlockSig, SIGILL); + sigdelset(&AuthBlockSig, SIGILL); +#endif +#ifdef SIGFPE + sigdelset(&BlockSig, SIGFPE); + sigdelset(&AuthBlockSig, SIGFPE); +#endif +#ifdef SIGSEGV + sigdelset(&BlockSig, SIGSEGV); + sigdelset(&AuthBlockSig, SIGSEGV); +#endif +#ifdef SIGBUS + sigdelset(&BlockSig, SIGBUS); + sigdelset(&AuthBlockSig, SIGBUS); +#endif +#ifdef SIGSYS + sigdelset(&BlockSig, SIGSYS); + sigdelset(&AuthBlockSig, SIGSYS); +#endif +#ifdef SIGCONT + sigdelset(&BlockSig, SIGCONT); + sigdelset(&AuthBlockSig, SIGCONT); +#endif +#ifdef SIGTERM + sigdelset(&AuthBlockSig, SIGTERM); +#endif +#ifdef SIGQUIT + sigdelset(&AuthBlockSig, SIGQUIT); +#endif +#ifdef SIGALRM + sigdelset(&AuthBlockSig, SIGALRM); +#endif +#else + UnBlockSig = 0; + BlockSig = sigmask(SIGHUP) | sigmask(SIGQUIT) | + sigmask(SIGTERM) | sigmask(SIGALRM) | + sigmask(SIGINT) | sigmask(SIGUSR1) | + sigmask(SIGUSR2) | sigmask(SIGCHLD) | + sigmask(SIGWINCH) | sigmask(SIGFPE); + AuthBlockSig = sigmask(SIGHUP) | + sigmask(SIGINT) | sigmask(SIGUSR1) | + sigmask(SIGUSR2) | sigmask(SIGCHLD) | + sigmask(SIGWINCH) | sigmask(SIGFPE); +#endif +} + + +/* Win32 signal handling is in backend/port/win32/signal.c */ +#ifndef WIN32 + +/* + * We need to check actually the system has the posix signals or not, but... + */ +#define HAVE_POSIX_SIGNALS +/* + * Set up a signal handler + */ +pool_sighandler_t +pool_signal(int signo, pool_sighandler_t func) +{ +#if !defined(HAVE_POSIX_SIGNALS) + return signal(signo, func); +#else + struct sigaction act, + oact; + + act.sa_handler = func; + sigemptyset(&act.sa_mask); + act.sa_flags = 0; + if (signo != SIGALRM) + act.sa_flags |= SA_RESTART; +#ifdef SA_NOCLDSTOP + if (signo == SIGCHLD) + act.sa_flags |= SA_NOCLDSTOP; +#endif + if (sigaction(signo, &act, &oact) < 0) + return SIG_ERR; + return oact.sa_handler; +#endif /* !HAVE_POSIX_SIGNALS */ +} + +#endif /* WIN32 */ diff --git a/pool_signal.h b/pool_signal.h new file mode 100644 index 0000000..02f1f64 --- /dev/null +++ b/pool_signal.h @@ -0,0 +1,58 @@ +/* -*-pgsql-c-*- */ +/* + * + * $Header$ + * + * pgpool: a language independent connection pool server for PostgreSQL + * written by Tatsuo Ishii + * + * Portions Copyright (c) 2003-2005, Tatsuo Ishii + * Portions Copyright (c) 2004, PostgreSQL Global Development Group + * + * Permission to use, copy, modify, and distribute this software and + * its documentation for any purpose and without fee is hereby + * granted, provided that the above copyright notice appear in all + * copies and that both that copyright notice and this permission + * notice appear in supporting documentation, and that the name of the + * author not be used in advertising or publicity pertaining to + * distribution of the software without specific, written prior + * permission. The author makes no representations about the + * suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * pool.h.: master definition header file + * + */ + +#ifndef POOL_SIGNAL_H +#define POOL_SIGNALH + +/* + * Signal stuff. Stolen from PostgreSQL source code. + */ +#include + +#ifdef HAVE_SIGPROCMASK +extern sigset_t UnBlockSig, + BlockSig, + AuthBlockSig; + +#define POOL_SETMASK(mask) sigprocmask(SIG_SETMASK, mask, NULL) +#else +extern int UnBlockSig, + BlockSig, + AuthBlockSig; + +#ifndef WIN32 +#define POOL_SETMASK(mask) sigsetmask(*((int*)(mask))) +#else +#define POOL_SETMASK(mask) pqsigsetmask(*((int*)(mask))) +int pqsigsetmask(int mask); +#endif +#endif + +typedef void (*pool_sighandler_t) (int); +extern pool_sighandler_t pool_signal(int signo, pool_sighandler_t func); +extern void poolinitmask(void); + +#endif /* POOL_SIGNAL_H */ diff --git a/pool_stream.c b/pool_stream.c new file mode 100644 index 0000000..3ae0940 --- /dev/null +++ b/pool_stream.c @@ -0,0 +1,600 @@ +/* -*-pgsql-c-*- */ +/* +* $Header$ +* +* pgpool: a language independent connection pool server for PostgreSQL +* written by Tatsuo Ishii +* +* Copyright (c) 2003-2005 Tatsuo Ishii +* +* Permission to use, copy, modify, and distribute this software and +* its documentation for any purpose and without fee is hereby +* granted, provided that the above copyright notice appear in all +* copies and that both that copyright notice and this permission +* notice appear in supporting documentation, and that the name of the +* author not be used in advertising or publicity pertaining to +* distribution of the software without specific, written prior +* permission. The author makes no representations about the +* suitability of this software for any purpose. It is provided "as +* is" without express or implied warranty. +* +* pool_stream.c: stream I/O modules +* +*/ + +#include "config.h" + +#include +#include +#include +#include +#include + +#include "pool.h" + +#define READBUFSZ 1024 + +static int mystrlen(char *str, int upper, int *flag); +static int mystrlinelen(char *str, int upper, int *flag); +static int save_pending_data(POOL_CONNECTION *cp, void *data, int len); +static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len); + +/* +* open read/write file descriptors. +* returns POOL_CONNECTION on success otherwise NULL. +*/ +POOL_CONNECTION *pool_open(int fd) +{ + POOL_CONNECTION *cp; + + cp = (POOL_CONNECTION *)malloc(sizeof(POOL_CONNECTION)); + if (cp == NULL) + { + pool_error("pool_open: malloc failed: %s", strerror(errno)); + return NULL; + } + + memset(cp, 0, sizeof(*cp)); + + cp->write_fd = fdopen(fd, "w"); + if (cp->write_fd == NULL) + { + pool_error("pool_open: fdopen failed: %s",strerror(errno)); + free(cp); + return NULL; + } + + /* initialize pending data buffer */ + cp->hp = malloc(READBUFSZ); + if (cp->hp == NULL) + { + pool_error("pool_open: malloc failed"); + return NULL; + } + cp->bufsz = READBUFSZ; + cp->po = 0; + cp->len = 0; + cp->sbuf = NULL; + cp->sbufsz = 0; + cp->buf2 = NULL; + cp->sbufsz = 0; + + cp->fd = fd; + return cp; +} + +/* +* close read/write file descriptors. +*/ +void pool_close(POOL_CONNECTION *cp) +{ + fclose(cp->write_fd); + free(cp->hp); + if (cp->sbuf) + free(cp->sbuf); + if (cp->buf2) + free(cp->buf2); + pool_discard_params(&cp->params); + free(cp); +} + +/* +* read len bytes from cp +* returns 0 on success otherwise -1. +*/ +int pool_read(POOL_CONNECTION *cp, void *buf, int len) +{ + static char readbuf[READBUFSZ]; + + int consume_size; + int readlen; + int notimeout; + + consume_size = consume_pending_data(cp, buf, len); + len -= consume_size; + buf += consume_size; + + /* if this is the secondary backend, then set timeout */ + notimeout = !cp->issecondary_backend; + + while (len > 0) + { + if (pool_check_fd(cp, notimeout)) + { + if (cp->issecondary_backend) + { + pool_log("pool_read: secondary data is not ready. abort this session"); + exit(1); + } + else + { + pool_error("pool_read: pool_check_fd failed (%s)", strerror(errno)); + return -1; + } + } + + readlen = read(cp->fd, readbuf, READBUFSZ); + if (readlen == -1) + { + pool_error("pool_read: read failed (%s)", strerror(errno)); + + if (cp->isbackend) + { + /* fatal error, notice to parent and exit */ + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + return -1; + } + } + else if (readlen == 0) + { + pool_error("pool_read: EOF encountered"); + + if (cp->isbackend) + { + /* fatal error, notice to parent and exit */ + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + /* + * if backend offers authentication method, frontend could close connection + */ + return -1; + } + } + + if (len < readlen) + { + /* overrun. we need to save remaining data to pending buffer */ + if (save_pending_data(cp, readbuf+len, readlen-len)) + return -1; + memmove(buf, readbuf, len); + break; + } + + memmove(buf, readbuf, readlen); + buf += readlen; + len -= readlen; + } + + return 0; +} + +/* +* read exactly len bytes from cp +* returns buffer address on success otherwise NULL. +*/ +char *pool_read2(POOL_CONNECTION *cp, int len) +{ + char *buf; + int req_size; + int alloc_size; + int consume_size; + int readlen; + int notimeout; + + req_size = cp->len + len; + + if (req_size > cp->bufsz2) + { + alloc_size = ((req_size+1)/READBUFSZ+1)*READBUFSZ; + cp->buf2 = realloc(cp->buf2, alloc_size); + if (cp->buf2 == NULL) + { + pool_error("pool_read2: failed to realloc"); + exit(1); + } + cp->bufsz2 = alloc_size; + } + + buf = cp->buf2; + + consume_size = consume_pending_data(cp, buf, len); + len -= consume_size; + buf += consume_size; + + /* if this is the secondary backend, then set timeout */ + notimeout = !cp->issecondary_backend; +#ifdef NOT_USED + pool_debug("notimeout: %d isbackend: %d issecondary_backend: %d", notimeout, + cp->isbackend, cp->issecondary_backend); +#endif + + while (len > 0) + { + if (pool_check_fd(cp, notimeout)) + { + if (cp->issecondary_backend) + { + pool_log("pool_read2: secondary data is not ready. abort this session"); + exit(1); + } + else + { + pool_error("pool_read2: pool_check_fd failed (%s)", strerror(errno)); + return NULL; + } + } + + readlen = read(cp->fd, buf, len); + if (readlen == -1) + { + pool_error("pool_read2: read failed (%s)", strerror(errno)); + + if (cp->isbackend) + { + /* fatal error, notice to parent and exit */ + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + return NULL; + } + } + else if (readlen == 0) + { + pool_error("pool_read2: EOF encountered"); + + if (cp->isbackend) + { + /* fatal error, notice to parent and exit */ + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + /* + * if backend offers authentication method, frontend could close connection + */ + return NULL; + } + } + + buf += readlen; + len -= readlen; + } + + return cp->buf2; +} + +/* +* write len bytes from cp +* returns 0 on success otherwise -1. +*/ +int pool_write(POOL_CONNECTION *cp, void *buf, int len) +{ + if (!cp->no_forward) + fwrite(buf, len, 1, cp->write_fd); + + return 0; +} + +/* +* flush write buffer +*/ +int pool_flush(POOL_CONNECTION *cp) +{ + if (fflush(cp->write_fd) != 0) + { + pool_error("pool_flush: fflush failed (%s)", strerror(errno)); + + if (cp->isbackend) + { + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + return -1; + } + } + return 0; +} + +/* +* combo of pool_write and pool_flush +*/ +int pool_write_and_flush(POOL_CONNECTION *cp, void *buf, int len) +{ + if (pool_write(cp, buf, len)) + return -1; + return pool_flush(cp); +} + +/* + * read a string until EOF or NULL is encountered. + * if line is not 0, read until new line is encountered. +*/ +char *pool_read_string(POOL_CONNECTION *cp, int *len, int line) +{ + int readp; + int readsize; + int readlen; + int strlength; + int flag; + int consume_size; + int notimeout; + +#ifdef DEBUG + static char pbuf[READBUFSZ]; +#endif + + *len = 0; + readp = 0; + + /* initialize read buffer */ + if (cp->sbufsz == 0) + { + cp->sbuf = malloc(READBUFSZ); + if (cp->sbuf == NULL) + { + pool_error("pool_read_string: malloc failed"); + return NULL; + } + cp->sbufsz = READBUFSZ; + *cp->sbuf = '\0'; + } + + /* any pending data? */ + if (cp->len) + { + if (line) + strlength = mystrlinelen(cp->hp+cp->po, cp->len, &flag); + else + strlength = mystrlen(cp->hp+cp->po, cp->len, &flag); + + /* buffer is too small? */ + if ((strlength + 1) > cp->sbufsz) + { + cp->sbufsz = ((strlength+1)/READBUFSZ+1)*READBUFSZ; + cp->sbuf = realloc(cp->sbuf, cp->sbufsz); + if (cp->sbuf == NULL) + { + pool_error("pool_read_string: realloc failed"); + return NULL; + } + } + + /* consume pending and save to read string buffer */ + consume_size = consume_pending_data(cp, cp->sbuf, strlength); + + *len = strlength; + + /* is the string null terminated? */ + if (consume_size == strlength && !flag) + { + /* not null or line terminated. + * we need to read more since we have not encountered NULL or new line yet + */ + readsize = cp->sbufsz - strlength; + readp = strlength; + } + else + { + pool_debug("pool_read_string: read all from pending data. po:%d len:%d", + cp->po, cp->len); + return cp->sbuf; + } + } else + { + readsize = cp->sbufsz; + } + + /* if this is the secondary backend, then set timeout */ + notimeout = !cp->issecondary_backend; + + for (;;) + { + if (pool_check_fd(cp, notimeout)) + { + if (cp->issecondary_backend) + { + pool_log("pool_read_string: secondary data is not ready. abort this session"); + exit(1); + } + else + { + pool_error("pool_read_string: pool_check_fd failed (%s)", strerror(errno)); + return NULL; + } + } + + readlen = read(cp->fd, cp->sbuf+readp, readsize); + if (readlen == -1) + { + pool_error("pool_read_string: read() failed. reason:%s", strerror(errno)); + + if (cp->isbackend) + { + notice_backend_error(!cp->issecondary_backend); + exit(1); + } + else + { + return NULL; + } + } + + /* check overrun */ + if (line) + strlength = mystrlinelen(cp->sbuf+readp, readlen, &flag); + else + strlength = mystrlen(cp->sbuf+readp, readlen, &flag); + + if (strlength < readlen) + { + save_pending_data(cp, cp->sbuf+readp+strlength, readlen-strlength); + *len += strlength; + pool_debug("pool_read_string: total result %d with pending data po:%d len:%d", *len, cp->po, cp->len); + return cp->sbuf; + } + + *len += readlen; + + /* encountered null or newline? */ + if (flag) + { + /* ok we have read all data */ + pool_debug("pool_read_string: total result %d ", *len); + break; + } + + readp += readlen; + readsize = READBUFSZ; + + if ((*len+readsize) > cp->sbufsz) + { + cp->sbufsz += READBUFSZ; + + cp->sbuf = realloc(cp->sbuf, cp->sbufsz); + if (cp->sbuf == NULL) + { + pool_error("pool_read_string: realloc failed"); + return NULL; + } + } + } + return cp->sbuf; +} + +/* + * returns the byte length of str, including \0, no more than upper. + * if encountered \0, flag is set to non 0. + * example: + * mystrlen("abc", 2) returns 2 + * mystrlen("abc", 3) returns 3 + * mystrlen("abc", 4) returns 4 + * mystrlen("abc", 5) returns 4 + */ +static int mystrlen(char *str, int upper, int *flag) +{ + int len; + + *flag = 0; + + for (len = 0;len < upper; len++, str++) + { + if (!*str) + { + len++; + *flag = 1; + break; + } + } + return len; +} + +/* + * returns the byte length of str terminated by \n or \0 (including \n or \0), no more than upper. + * if encountered \0 or \n, flag is set to non 0. + * example: + * mystrlinelen("abc", 2) returns 2 + * mystrlinelen("abc", 3) returns 3 + * mystrlinelen("abc", 4) returns 4 + * mystrlinelen("abc", 5) returns 4 + * mystrlinelen("abcd\nefg", 4) returns 4 + * mystrlinelen("abcd\nefg", 5) returns 5 + * mystrlinelen("abcd\nefg", 6) returns 5 + */ +static int mystrlinelen(char *str, int upper, int *flag) +{ + int len; + + *flag = 0; + + for (len = 0;len < upper; len++, str++) + { + if (!*str || *str == '\n') + { + len++; + *flag = 1; + break; + } + } + return len; +} + +/* + * save pending data + */ +static int save_pending_data(POOL_CONNECTION *cp, void *data, int len) +{ + int reqlen; + size_t realloc_size; + char *p; + + /* to be safe */ + if (cp->len == 0) + cp->po = 0; + + reqlen = cp->po + cp->len + len; + + /* pending buffer is enough? */ + if (reqlen > cp->bufsz) + { + /* too small, enlarge it */ + realloc_size = (reqlen/READBUFSZ+1)*READBUFSZ; + p = realloc(cp->hp, realloc_size); + if (p == NULL) + { + pool_error("save_pending_data: realloc failed"); + return -1; + } + + cp->bufsz = realloc_size; + cp->hp = p; + } + + memmove(cp->hp + cp->po + cp->len, data, len); + cp->len += len; + + return 0; +} + +/* + * consume pending data. returns actually consumed data length. + */ +static int consume_pending_data(POOL_CONNECTION *cp, void *data, int len) +{ + int consume_size; + + if (cp->len <= 0) + return 0; + + consume_size = Min(len, cp->len); + memmove(data, cp->hp + cp->po, consume_size); + cp->len -= consume_size; + + if (cp->len <= 0) + cp->po = 0; + else + cp->po += consume_size; + + return consume_size; +} diff --git a/version.h b/version.h new file mode 100644 index 0000000..812dce5 --- /dev/null +++ b/version.h @@ -0,0 +1 @@ +#define PGPOOLVERSION "kaku" -- 2.39.5