README.euc_jp pgpool.spec \
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 ps_status.c strlcpy.c
+ pool_signal.h pool_signal.c ps_status.c strlcpy.c \
+ pool_hba.c pool_list.h pool_list.c pool_path.h pool_path.c \
+ pool_type.h pool_ip.h pool_ip.c pool_hba.conf.sample
DEFS = @DEFS@ \
-DDEFAULT_CONFIGDIR=\"$(sysconfdir)\"
-sysconf_DATA = pgpool.conf.sample
+sysconf_DATA = pgpool.conf.sample pool_hba.conf.sample
AM_CPPFLAGS = -Wall -Wmissing-prototypes -Wmissing-declarations -D_GNU_SOURCE
$(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__aclocal_m4_deps = $(top_srcdir)/ac_func_accept_argtypes.m4 \
+ $(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 \
pool_config.$(OBJEXT) pool_error.$(OBJEXT) \
pool_process_query.$(OBJEXT) pool_stream.$(OBJEXT) \
pool_connection_pool.$(OBJEXT) pool_params.$(OBJEXT) \
- pool_signal.$(OBJEXT) ps_status.$(OBJEXT) strlcpy.$(OBJEXT)
+ pool_signal.$(OBJEXT) ps_status.$(OBJEXT) strlcpy.$(OBJEXT) \
+ pool_hba.$(OBJEXT) pool_list.$(OBJEXT) pool_path.$(OBJEXT) \
+ pool_ip.$(OBJEXT)
pgpool_OBJECTS = $(am_pgpool_OBJECTS)
pgpool_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
README.euc_jp pgpool.spec \
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 ps_status.c strlcpy.c
+ pool_signal.h pool_signal.c ps_status.c strlcpy.c \
+ pool_hba.c pool_list.h pool_list.c pool_path.h pool_path.c \
+ pool_type.h pool_ip.h pool_ip.c pool_hba.conf.sample
-sysconf_DATA = pgpool.conf.sample
+sysconf_DATA = pgpool.conf.sample pool_hba.conf.sample
AM_CPPFLAGS = -Wall -Wmissing-prototypes -Wmissing-declarations -D_GNU_SOURCE
man_MANS = pgpool.8
CLEANFILES = pgpool.8
@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_hba.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_ip.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_params.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pool_path.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@
secondary server.
Moreover, pgpool supports scheduled switch over. See
- "9. Switchover" for more details.
+ "10. Switchover" for more details.
1.1 About replication facility of pgpool
Default installation directories are:
- /usr/local/bin/pgpool pgpool executable
- /usr/local/etc/pgpool.conf.sample example configuration file
+ /usr/local/bin/pgpool pgpool executable
+ /usr/local/etc/pgpool.conf.sample example configuration file
+ /usr/local/etc/pool_hba.conf.sample example HBA configuration file
You could change the installation directory by giving --prefix
option to configure:
pgpool.conf is the configuration file for pgpool.
- Copy pgpool.conf.sample as pgpool.conf and change it if neccessary.
+ Copy pgpool.conf.sample as pgpool.conf and change it if necessary.
Here is a explanation of pgpool.conf's grammar.
to PostgreSQL, this allows for observing queries without engaging in full
debugging.
-7. Starting pgpool
+ log_connections
+
+ If true, all incoming connections will be printed to the log.
+
+ enable_pool_hba
+
+ If true, use pool_hba.conf for client authentication. In pgpool 3.2,
+ the default value is false. This parameter is planned to be deleted
+ in the next version of pgpool, and pool_hba.conf will always be used.
+ See "7. Setting up pool_hba.conf for client authentication".
+
+7. Setting up pool_hba.conf for client authentication (HBA)
+
+ Just like pg_hba.conf with PostgreSQL, pgpool supports a similar
+ client authentication function using a configuration file called
+ "pool_hba.conf".
+
+ When you install pgpool, pool_hba.conf.sample will be installed in
+ "/usr/local/etc", which is the default directory for configuration
+ files.
+
+ Copy pool_hba.conf.sample as pool_hba.conf and edit it if necessary.
+ By default, pool_hba authentication is disabled for backward
+ compatibility. To enable it, set enable_pool_hba to true in
+ pgpool.conf. See "6. Setting up pgpool.conf" for more detail.
+
+ The format of pool_hba.conf file follows very closely to pg_hba.conf.
+
+ local DATABASE USER METHOD [OPTION]
+ host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+
+ See "pool_hba.conf.sample" for details of each field.
+
+ Here are the limitations of pool_hba.
+
+ * "hostssl" connection type is not supported
+
+ "hostssl" is invalid since pgpool currently does not support SSL
+ connections.
+
+ * "samegroup" for DATABASE field is not supported
+
+ Since pgpool does not know anything about users in the backend server,
+ database name is simply checked against the entries in the DATABASE
+ field of pool_hba.conf.
+
+ * group names following "+" for USER field is not supported
+
+ This is the same reason as in the "samegroup" described above. A
+ user name is simply checked against the entries in the USER field
+ of pool_hba.conf.
+
+ * IPv6 for IP address/mask is not supported
+
+ pgpool currently does not support IPv6.
+
+ * Only "trust", "reject" and "pam" for METHOD field are supported
+
+ Again, this is the same reason as in the "samegroup" described above.
+ pgpool does not hold user/password information.
+
+ Note that everything described in this section is about a client authen-
+ tication between a client and pgpool; a client still have to go through
+ an authentication process with PostgreSQL. As far as pool_hba is concerned,
+ it does not matter if a user name and/or database name given by a client
+ (i.e. psql -U testuser testdb) really exist in the backend. pool_hba only
+ cares if a match in the pool_hba.conf is found or not.
+
+ PAM authenticaion is supported using user information on the host where
+ pgpool is executed. To enable PAM support in pgpool, specify "--with-pam"
+ option to configure:
+
+ configure --with-pam
+
+8. Starting pgpool
The simplist way to start pgpool is:
the path to the configuration file.
+ -a path
+
+ the path to the pool_hba configuration file.
+
-n
do not start as daemon. Error messages go to stdout or stderr. Thus
print the help message and quit
-8. Stopping pgpool
+9. Stopping pgpool
You can stop pgpool by using "stop" option:
$ pgpool -m i[mmediate] stop
-9. switchover
+10. switchover
For maintenance purpose, scheduled switching or degeneration is
supported.
If there's only one PostgreSQL server, pgpool switch will just
restart pgpool child processes.
-10. how to get logging
+11. how to get logging
You could save messages from pgpool to a file by starting it with
-n option:
pgpool -n 2>&1 |logger -t pgpool -p local0.info&
-11. getting internal status of pgpool
+12. 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
+ item | value | description
------------------------------+------------------------------------------------------+------------------------------------------------------------------------
listen_addresses | * | host name(s) or IP address(es) to listen to
port | 9998 | pgpool accepting port number
num_init_children | 32 | # of children initially pre-forked
child_life_time | 0 | if idle for this seconds, child exits
connection_life_time | 0 | if idle for this seconds, connection closes
+ child_max_connections | 0 | if max_connections received, chile exits
max_pool | 2 | max # of connection pool per child
logdir | /tmp | logging directory
backend_socket_dir | /tmp | Unix domain socket directory for the PostgreSQL server
health_check_period | 0 | health check period
health_check_user | t-ishii | health check user
insert_lock | 1 | insert lock
+ ignore_leading_white_space | 0 | ignore leading white spaces
current_backend_host_name | | current master host name
current_backend_port | 5432 | current master port #
replication_enabled | 1 | 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
+ log_statement | 0 | if true, print all statements to the log
+ log_connections | 1 | if true, print incoming connections to the log
+ enable_pool_hba | 1 | if true, use pool_hba.conf for client authentication
server_status | master( on 5432) up secondary( on 5433) up | server status
-(34 rows)
+(39 rows)
By using contrib/dblink, you can see part of the result of
show_pool_status someting like:
port | 9999
(1 row)
-12. Playing with regression test
+13. 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
+14. Playing with benchmarking
Here is a brief explanation how to play with benchmarking using pgbench/PHP/ab.
$ /usr/local/apache/bin/ab -c 100 -n 1000 "http://localhost/bench.php"
-14. master/slave mode
+15. 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
2) in all other case, quries are sent to only master
-15. Multiple simultaneous instances of pgpool
+16. Multiple simultaneous instances of pgpool
In order to run multiple instances of pgpool on the same server
simultaneously (in order to have two separate, non-conflicting
¤Ê¤ª¡¤¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä½ÌÂ౿ž¤Ï²¿¤«¾ã³²¤¬µ¯¤¤¿¤³¤È¤ò¥È¥ê¥¬¤Ë¤·¤Æ
µ¯Æ°¤µ¤ì¤Þ¤¹¤¬¡¤¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¤Ê¤É¤Î¤¿¤á¤Ë°Õ¿ÞŪ¤Ë¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä
- ½ÌÂ౿ž¥â¡¼¥É¤Ë°Ü¹Ô¤¹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡¥¾ÜºÙ¤Ï¡Ö9. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð¡×
+ ½ÌÂ౿ž¥â¡¼¥É¤Ë°Ü¹Ô¤¹¤ë¤³¤È¤â¤Ç¤¤Þ¤¹¡¥¾ÜºÙ¤Ï¡Ö10. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð¡×
¤ò¤´Í÷²¼¤µ¤¤¡¥
1.1 ¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤Ë¤Ä¤¤¤Æ
make¤ògmake¤ËÆÉ¤ßÂØ¤¨¤Æ¤¯¤À¤µ¤¤)¡¥¥Ç¥Õ¥©¥ë¥È¤Î¥¤¥ó¥¹¥È¡¼¥ëÀè¤Ï¡¤
/usr/local°Ê²¼¤Ç°Ê²¼¤Î¤è¤¦¤Ê¥Õ¥¡¥¤¥ë¤¬¥¤¥ó¥¹¥È¡¼¥ë¤µ¤ì¤Þ¤¹¡¥
- /usr/local/bin/pgpool ¥×¥í¥°¥é¥àËÜÂÎ
- /usr/local/etc/pgpool.conf.sample ÀßÄê¥Õ¥¡¥¤¥ë¥µ¥ó¥×¥ë
+ /usr/local/bin/pgpool ¥×¥í¥°¥é¥àËÜÂÎ
+ /usr/local/etc/pgpool.conf.sample ÀßÄê¥Õ¥¡¥¤¥ë¥µ¥ó¥×¥ë
+ /usr/local/etc/pool_hba.conf.sample HBAÀßÄê¥Õ¥¡¥¤¥ë¥µ¥ó¥×¥ë
¥¤¥ó¥¹¥È¡¼¥ëÀè¤òÊѹ¹¤¹¤ë¾ì¹ç¤Ï¡¤configure --prefix=path... ¤È¤·
¤Æ¤¯¤À¤µ¤¤¡¥
log_statement¥ª¥×¥·¥ç¥ó¤È»÷¤Æ¤¤¤Æ¡¤¥Ç¥Ð¥Ã¥°¥ª¥×¥·¥ç¥ó¤¬¤Ê¤¤¤È¤¤Ç¤â
Ì䤤¹ç¤ï¤»¤ò¥í¥°½ÐÎϤ·¤ÆÄ´¤Ù¤ë¤³¤È¤¬¤Ç¤¤ë¤Î¤ÇÊØÍø¤Ç¤¹¡¥
-7. pgpool¤Îµ¯Æ°
+ log_connections
+
+ true¤Ê¤é¤Ð¡¢Á´¤Æ¤Î¥¯¥é¥¤¥¢¥ó¥ÈÀܳ¤ò¥í¥°¤Ø½ÐÎϤ·¤Þ¤¹¡£
+
+ enable_pool_conf
+
+ true¤Ê¤é¤Ð¡¢pool_hba.conf¤Ë½¾¤Ã¤Æ¥¯¥é¥¤¥¢¥ó¥Èǧ¾Ú¤ò¹Ô¤¤¤Þ¤¹¡£pgpool
+ 3.2¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏfalse¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¤¬¡¢¼¡¤Î¥ê¥ê¡¼¥¹¥Ð¡¼¥¸¥ç¥ó¤Ç
+ ¤Ï¤³¤Î¥Ñ¥é¥á¡¼¥¿¤Ïºï½ü¤µ¤ì¡¢¾ï¤Ëpool_hba.conf¤Ë¤è¤ë¥¯¥é¥¤¥ó¥¢¥ó¥Èǧ
+ ¾Ú¤¬¹Ô¤ï¤ì¤ëͽÄê¤Ç¤¹¡£¾ÜºÙ¤Ï¡Ö7. ¥¯¥é¥¤¥¢¥ó¥Èǧ¾Ú(HBA)¤Î¤¿¤á¤Î
+ pool_hba.confÀßÄêÊýË¡¡×¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡£
+
+7. ¥¯¥é¥¤¥¢¥ó¥Èǧ¾Ú(HBA)¤Î¤¿¤á¤Î pool_hba.conf ÀßÄêÊýË¡
+
+ PostgreSQL¤Îpg_hba.conf¤ÈƱ¤¸¤è¤¦¤Ëpgpool¤Ç¤âpool_config.conf¥Õ¥¡¥¤
+ ¥ë¤ò»È¤Ã¤¿¥¯¥é¥¤¥¢¥ó¥Èǧ¾Ú¤¬¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤Þ¤¹¡£
+
+ pgpool¤ò¥¤¥ó¥¹¥È¡¼¥ë¤¹¤ë¤È¥Ç¥Õ¥©¥ë¥È¥¤¥ó¥¹¥È¡¼¥ëÀè¤ÎÀßÄê¥Õ¥¡¥¤¥ë¥Ç¥£
+ ¥ì¥¯¥È¥ê"/usr/local/etc"¤Ëpool_hba.conf.sample¤¬°ì½ï¤Ë¥¤¥ó¥¹¥È¡¼¥ë
+ ¤µ¤ì¤Þ¤¹¡£
+
+ ¤³¤Îpool_hba.conf.sample¥Õ¥¡¥¤¥ë¤òpool_hba.conf¤È¤·¤Æ¥³¥Ô¡¼¤·¡¢É¬Í×
+ ¤Ç¤¢¤ì¤ÐÊÔ½¸¤·¤Æ¤¯¤À¤µ¤¤¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ïpool_hba¤Ë¤è¤ëǧ¾Ú¤Ï̵¸ú¤Ë
+ ¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡£¤³¤ì¤Ï°ÊÁ°¤Îpgpool¤È¤Î¸ß´¹À¤òÊݤĤ¿¤á¤Ç¤¹¡£Í¸ú¤Ë¤¹
+ ¤ë¤¿¤á¤Ë¤Ïpgpool.conf¤Îenable_pool_hba¤òtrue¤ËÀßÄꤹ¤ëɬÍפ¬¤¢¤ê¤Þ
+ ¤¹¡£
+
+ pool_hba.conf¤Î¥Õ¥©¡¼¥Þ¥Ã¥È¤Ïpg_hba.conf¤Î¤â¤Î¤È¤Û¤È¤ó¤ÉƱ¤¸¤Ç¤¹¡£
+
+ local DATABASE USER METHOD [OPTION]
+ host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+
+ ³Æ¥Õ¥£¡¼¥ë¥É¤ÇÀßÄê¤Ç¤¤ëÃͤξܺ٤Ï"pool_hba.conf.sample"¤ò»²¾È¤·¤Æ
+ ¤¯¤À¤µ¤¤¡£
+
+ °Ê²¼¤Ïpool_hba¤ÎÀ©¸Â»ö¹à¤Ç¤¹¡£
+
+ * "hostssl"Àܳ¥¿¥¤¥×¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó
+
+ ¸½ºßpgpool¤ÏSSLÀܳ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¤Î¤Ç"hostssl"¤Ï»ØÄꤹ¤ë¤³
+ ¤È¤¬¤Ç¤¤Þ¤»¤ó¡£
+
+ * DATABASE¥Õ¥£¡¼¥ë¥ÉÃͤȤ·¤Æ"samegroup"¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó
+
+ pgpool¤Ï¥Ð¥Ã¥¯¥¨¥ó¥É¥µ¡¼¥Ð¤Ë¤¢¤ë¥æ¡¼¥¶¾ðÊó¤ò»öÁ°¤ËÃΤë»ö¤¬¤Ç¤¤Ê
+ ¤¤¤¿¤á¡¢¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾¤Ïpool_hba.conf¤Ë¤¢¤ëÃͤΤߤÈÈæ³Ó¤µ¤ì¤Þ¤¹¡£
+ ¤Ê¤Î¤Ç¥°¥ë¡¼¥×¤Ë´Ø¤¹¤ëǧ¾Ú¤Ïpool_hba¤Ç¹Ô¤¦¤³¤È¤¬¤Ç¤¤Þ¤»¤ó¡£
+
+ * USER¥Õ¥£¡¼¥ë¥ÉÃͤȤ·¤Æ"+"¤ò»È¤Ã¤¿¥°¥ë¡¼¥×»ØÄê¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó
+
+ ¾åµ¤Î"samegroup"¤ÈƱ¤¸Íýͳ¤Ç¡¢¥æ¡¼¥¶Ì¾¤Ïpool_hba.conf¤Ë¤¢¤ëÃͤÎ
+ ¤ß¤ÈÈæ³Ó¤µ¤ì¤Þ¤¹¡£¥°¥ë¡¼¥×¤Ë´Ø¤¹¤ëǧ¾Ú¤Ïpool_hba¤Ç¹Ô¤¦¤³¤È¤Ï¤Ç¤
+ ¤Þ¤»¤ó¡£
+
+ * IPv6¥¢¥É¥ì¥¹/¥Þ¥¹¥¯É½µË¡¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó
+
+ ¸½ºßpgpool¤ÏIPv6¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Þ¤»¤ó¡£
+
+ * "trust", "reject", "pam"°Ê³°¤Î¥á¥½¥Ã¥É¤Ï¥µ¥Ý¡¼¥È¤µ¤ì¤Þ¤»¤ó
+
+ ¤³¤ì¤â¾åµ¤Î"samegroup"¤ÈƱ¤¸Íýͳ¤Ë¤è¤ë¤â¤Î¤Ç¤¹¡£pgpool¤Ï¥Ð¥Ã¥¯¥¨
+ ¥ó¥É¤Î¥æ¡¼¥¶/¥Ñ¥¹¥ï¡¼¥É¾ðÊó¤ò»ý¤Ã¤Æ¤¤¤Ê¤¤¤Î¤Ç¡¢¥Ð¥Ã¥¯¥¨¥ó¥É¤ËÊݸ
+ ¤µ¤ì¤Æ¤¤¤ë¥Ñ¥¹¥ï¡¼¥É¤ò»È¤Ã¤¿Ç§¾Ú¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤¤Þ¤»¤ó¡£
+
+ ¤³¤³¤ÇÀâÌÀ¤µ¤ì¤¿µ¡Ç½¡¢À©¸Â¤Ï¥¯¥é¥¤¥¢¥ó¥È¤Èpgpool´Ö¤Ç¹Ô¤ï¤ì¤ë¥¯¥é¥¤
+ ¥¢¥ó¥Èǧ¾Ú¤Ë¤Ä¤¤¤Æ¤À¤È¤¤¤¦¤³¤È¤ËÃí°Õ¤·¤Æ¤¯¤À¤µ¤¤¡£¥¯¥é¥¤¥ó¥¢¥ó¥È¤Ï
+ pgpool¤Î¥¯¥é¥¤¥¢¥ó¥Èǧ¾Ú¤ËÀ®¸ù¤·¤¿¤È¤·¤Æ¤â¡¢PostgreSQL¤Ë¤è¤ë¥¯¥é¥¤
+ ¥¢¥ó¥Èǧ¾Ú¤ËÀ®¸ù¤·¤Ê¤¤¤ÈÀܳ¾õÂ֤Ȥʤê¤Þ¤»¤ó¡£pool_hba¤Ë¤È¤Ã¤Æ¤Ï¥¯
+ ¥é¥¤¥¢¥ó¥È¤Ë»ØÄꤵ¤ì¤¿¥æ¡¼¥¶Ì¾¤ä¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾
+ (Îã. psql -U testuser testdb)¤¬¼ÂºÝ¤Ë¥Ð¥Ã¥¯¥¨¥ó¥É¾å¤Ë¸ºß¤¹¤ë¤«¤É¤¦
+ ¤«¤ÏÌäÂê¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡£¤½¤ì¤¬pool_hba.conf¤ÎÃͤȥޥåÁ¤¹¤ë¤«¤É¤¦¤«
+ ¤Ç¥Á¥§¥Ã¥¯¤¬¹Ô¤ï¤ì¤Þ¤¹¡£
+
+ pgpool¤¬²ÔƯ¤¹¤ë¥Û¥¹¥È¾å¤Î¥æ¡¼¥¶¾ðÊó¤ò»È¤Ã¤¿PAMǧ¾Ú¤òÍøÍѤ¹¤ë¤³¤È¤¬
+ ¤Ç¤¤Þ¤¹¡£pgpool¤òPAM¥µ¥Ý¡¼¥ÈÉÕ¤¤Ç¥Ó¥ë¥É¤¹¤ë¤Ë¤Ïconfigure¥ª¥×¥·¥ç
+ ¥ó¤Ë"--with-pam"¤ò»ØÄꤷ¤Æ¤¯¤À¤µ¤¤¡£
+
+ configure --with-pam
+
+8. pgpool¤Îµ¯Æ°
pgpool¤òµ¯Æ°¤¹¤ë¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤Ï¡¤
¥Ø¥ë¥×¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ·¤Æ½ªÎ»¤·¤Þ¤¹¡¥
-8. pgpool¤Î½ªÎ»
+9. pgpool¤Î½ªÎ»
¡Östop¡×¥ª¥×¥·¥ç¥ó¤ò»È¤¤¤Þ¤¹¡¥
¤È¤¹¤ë¤È¡¤pgpool stop¤ÈƱ¤¸Æ°ºî¤ò¤·¤Þ¤¹¡¥
-9. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð
+10. ¥¹¥¤¥Ã¥Á¥ª¡¼¥Ð
¥á¥¤¥ó¥Æ¥Ê¥ó¥¹¤Ê¤É¤Î¤¿¤á¤Ë°Õ¿ÞŪ¤Ë¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤ä½ÌÂ౿ž¥â¡¼¥É¤Ë
°Ü¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤¤Þ¤¹¡¥
¥ó¥È¤«¤épgpool¤Ø¤Î¥³¥Í¥¯¥·¥ç¥ó¤ò¶¯À©Åª¤Ë°ìÅÙÀÚÃǤ·¡¤pgpool¤Î»Ò¥×¥í
¥»¥¹¤¬ºÆµ¯Æ°¤µ¤ì¤Þ¤¹¡¥
-10. ¥í¥°¤Î¼è¤êÊý
+11. ¥í¥°¤Î¼è¤êÊý
pgpool¤ò-n¥ª¥×¥·¥ç¥óÉդǵ¯Æ°¤¹¤ë¤È¡¤stderr(ɸ½à¥¨¥é¡¼½ÐÎÏ)¤Ë¥¨¥é¡¼
¤ä½ÅÂç¤Ê¾ðÊó(¤¿¤È¤¨¤Ð¥Õ¥§¥¤¥ë¥ª¡¼¥Ð¤·¤¿¤è¤¦¤Ê¾ì¹ç)¤Ë´Ø¤¹¤ë¥á¥Ã¥»¡¼
Apr 13 15:07:11 srapc1977 4·î 13 15:07:11 pgpool: log: pid 2038: failover from (5432) to (5433) done.
-11. pgpool¤ÎÆâÉô¾ðÊó¤Î¼èÆÀ
+12. pgpool¤ÎÆâÉô¾ðÊó¤Î¼èÆÀ
pgpool¤¬Ç§¼±¤·¤Æ¤¤¤ëÀßÄê¥Õ¥¡¥¤¥ë(pgpool.conf)¤ÎÆâÍÆ¤ä¡¤¸½ºß¤Î¥ì¥×
¥ê¥±¡¼¥·¥ç¥ó¤Î¾õÂÖ¤òSQL¤òȯ¹Ô¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¼èÆÀ¤¹¤ë¤³¤È¤¬¤Ç¤¤Þ
(¥Ç¡¼¥¿¥Ù¡¼¥¹Ì¾¤Ï²¿¤Ç¤â¤«¤Þ¤¤¤Þ¤»¤ó)¡¥
- item | value | description
-------------------------------+------------------------------------------------------+------------------------------------------------------------------------
+ item | value | description --------------------------------+------------------------------------------------------+------------------------------------------------------------------------
listen_addresses | * | host name(s) or IP address(es) to listen to
port | 9998 | pgpool accepting port number
socket_dir | /tmp | pgpool socket directory
num_init_children | 32 | # of children initially pre-forked
child_life_time | 0 | if idle for this seconds, child exits
connection_life_time | 0 | if idle for this seconds, connection closes
+ child_max_connections | 0 | if max_connections received, chile exits
max_pool | 2 | max # of connection pool per child
logdir | /tmp | logging directory
backend_socket_dir | /tmp | Unix domain socket directory for the PostgreSQL server
health_check_period | 0 | health check period
health_check_user | t-ishii | health check user
insert_lock | 1 | insert lock
+ ignore_leading_white_space | 0 | ignore leading white spaces
current_backend_host_name | | current master host name
current_backend_port | 5432 | current master port #
replication_enabled | 1 | 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
+ log_statement | 0 | if true, print all statements to the log
+ log_connections | 1 | if true, print incoming connections to the log
+ enable_pool_hba | 1 | if true, use pool_hba.conf for client authentication
server_status | master( on 5432) up secondary( on 5433) up | server status
-(34 rows)
+(39 rows)
contrib/dblink¤ò»È¤¨¤Ð¡¤°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ°ìÉô¤Î·ë²Ì¤À¤±¤ò¸«¤ë¤³¤È¤¬¤Ç¤
¤Þ¤¹¡¥
port | 9999
(1 row)
-12. regression test¤Î¼Â»Ü
+13. regression test¤Î¼Â»Ü
°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æpgpool¤òÊ»ÍѤ·¤Æregression test¤ò¹Ô¤¦¤³¤È¤¬¤Ç¤¤Þ¤¹¡¥
¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¥â¡¼¥É¤Çregression test¤ò¤¹¤ë¤Èɬ¤ºtablespace¤Î¥Æ¥¹
¥È¤¬fail¤·¤Þ¤¹¤¬¡¤¤³¤ì¤Ï°Û¾ï¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥
-13. ¥Ù¥ó¥Á¥Þ¡¼¥¯¤Î¼Â»Ü
+14. ¥Ù¥ó¥Á¥Þ¡¼¥¯¤Î¼Â»Ü
¥Ù¥ó¥Á¥Þ¡¼¥¯¤ò¼Â»Ü¤¹¤ë¤Ë¤Ï¤¤¤í¤¤¤í¤ÊÊýË¡¤¬¤¢¤ê¤Þ¤¹¤¬¡¤¤³¤³¤Ç¤Ï
pgbench¤ÈPHP¤½¤ì¤Ëab¤ò»È¤Ã¤¿´Êñ¤ÊÊýË¡¤ò¤´¾Ò²ð¤·¤Þ¤¹¡¥
$ /usr/local/apache/bin/ab -c 100 -n 1000 "http://localhost/bench.php"
-14. master/slave¥â¡¼¥É
+15. master/slave¥â¡¼¥É
master/slave¥â¡¼¥É¤Ï¡¤Slony-I¤Î¤è¤¦¤Ê¡¤master/slave¼°¤Î¥ì¥×¥ê¥±¡¼¥·¥ç
¥ó¥½¥Õ¥È¤Ë¥ì¥×¥ê¥±¡¼¥·¥ç¥ó¤ò¤Þ¤«¤»¤ë¥â¡¼¥É¤Ç¤¹¡¥¤³¤Î¥â¡¼¥É¤Ç»È¤¦¤¿¤á¤Ë
2) 1)°Ê³°¤Î¾ì¹ç¤Ï¡¤¥Þ¥¹¥¿¤À¤±¤ËÌ䤤¹ç¤ï¤»¤¬Á÷¤é¤ì¤Þ¤¹¡¥
-15. Ê£¿ô¤Îpgpool¤òƱ¤¸¥Û¥¹¥È¤ÇΩ¤Á¾å¤²¤ë¤Ë¤Ï
+16. Ê£¿ô¤Îpgpool¤òƱ¤¸¥Û¥¹¥È¤ÇΩ¤Á¾å¤²¤ë¤Ë¤Ï
Ê£¿ô¤Îpgpool¤òƱ¤¸¥Û¥¹¥È¤ÇΩ¤Á¾å¤²¤ë¤Ë¤Ï(¤¿¤È¤¨¤Ð2¤Ä¤ÎDB¥¯¥é¥¹¥¿¤òÊÌ¡¹
¤Ëpgpool¤Ç°·¤¦¥±¡¼¥¹)¡¤2¤Ä¤ÎÀßÄê¥Õ¥¡¥¤¥ë¤òºî¤ê¤Þ¤¹¡¥
--- /dev/null
+# $PostgreSQL: pgsql/config/ac_func_accept_argtypes.m4,v 1.6 2003/11/29 19:51:17 pgsql Exp $
+# This comes from the official Autoconf macro archive at
+# <http://research.cys.de/autoconf-archive/>
+# (I removed the $ before the Id CVS keyword below.)
+
+
+dnl @synopsis AC_FUNC_ACCEPT_ARGTYPES
+dnl
+dnl Checks the data types of the three arguments to accept(). Results are
+dnl placed into the symbols ACCEPT_TYPE_RETURN and ACCEPT_TYPE_ARG[123],
+dnl consistent with the following example:
+dnl
+dnl #define ACCEPT_TYPE_RETURN int
+dnl #define ACCEPT_TYPE_ARG1 int
+dnl #define ACCEPT_TYPE_ARG2 struct sockaddr *
+dnl #define ACCEPT_TYPE_ARG3 socklen_t
+dnl
+dnl This macro requires AC_CHECK_HEADERS to have already verified the
+dnl presence or absence of sys/types.h and sys/socket.h.
+dnl
+dnl NOTE: This is just a modified version of the AC_FUNC_SELECT_ARGTYPES
+dnl macro. Credit for that one goes to David MacKenzie et. al.
+dnl
+dnl @version Id: ac_func_accept_argtypes.m4,v 1.1 1999/12/03 11:29:29 simons Exp $
+dnl @author Daniel Richard G. <skunk@mit.edu>
+dnl
+
+# PostgreSQL local changes: In the original version ACCEPT_TYPE_ARG3
+# is a pointer type. That's kind of useless because then you can't
+# use the macro to define a corresponding variable. We also make the
+# reasonable(?) assumption that you can use arg3 for getsocktype etc.
+# as well (i.e., anywhere POSIX.2 has socklen_t).
+#
+# arg2 can also be `const' (e.g., RH 4.2). Change the order of tests
+# for arg3 so that `int' is first, in case there is no prototype at all.
+#
+# Solaris 7 and 8 have arg3 as 'void *' (disguised as 'Psocklen_t'
+# which is *not* 'socklen_t *'). If we detect that, then we assume
+# 'int' as the result, because that ought to work best.
+#
+# On Win32, accept() returns 'unsigned int PASCAL'
+
+AC_DEFUN([AC_FUNC_ACCEPT_ARGTYPES],
+[AC_MSG_CHECKING([types of arguments for accept()])
+ AC_CACHE_VAL(ac_cv_func_accept_return,dnl
+ [AC_CACHE_VAL(ac_cv_func_accept_arg1,dnl
+ [AC_CACHE_VAL(ac_cv_func_accept_arg2,dnl
+ [AC_CACHE_VAL(ac_cv_func_accept_arg3,dnl
+ [for ac_cv_func_accept_return in 'int' 'unsigned int PASCAL'; do
+ for ac_cv_func_accept_arg1 in 'int' 'unsigned int'; do
+ for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do
+ for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do
+ AC_TRY_COMPILE(
+[#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+extern $ac_cv_func_accept_return accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *);],
+ [], [ac_not_found=no; break 4], [ac_not_found=yes])
+ done
+ done
+ done
+ done
+ if test "$ac_not_found" = yes; then
+ AC_MSG_ERROR([could not determine argument types])
+ fi
+ if test "$ac_cv_func_accept_arg3" = "void"; then
+ ac_cv_func_accept_arg3=int
+ fi
+ ])dnl AC_CACHE_VAL
+ ])dnl AC_CACHE_VAL
+ ])dnl AC_CACHE_VAL
+ ])dnl AC_CACHE_VAL
+ AC_MSG_RESULT([$ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *])
+ AC_DEFINE_UNQUOTED(ACCEPT_TYPE_RETURN, $ac_cv_func_accept_return,
+ [Define to the return type of 'accept'])
+ AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG1, $ac_cv_func_accept_arg1,
+ [Define to the type of arg 1 of 'accept'])
+ AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG2, $ac_cv_func_accept_arg2,
+ [Define to the type of arg 2 of 'accept'])
+ AC_DEFINE_UNQUOTED(ACCEPT_TYPE_ARG3, $ac_cv_func_accept_arg3,
+ [Define to the type of arg 3 of 'accept'])
+])
AC_SUBST([am__untar])
]) # _AM_PROG_TAR
+m4_include([ac_func_accept_argtypes.m4])
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/un.h>
+#include <arpa/inet.h>
+#include <netdb.h>
#ifdef HAVE_NETINET_TCP_H
#include <netinet/tcp.h>
#endif
#endif
#include "pool.h"
+#include "pool_ip.h"
#ifdef NONE_BLOCK
static void set_nonblock(int fd);
goto retry_startup;
}
+ if (pool_config.enable_pool_hba)
+ {
+ /*
+ * do client authentication.
+ * Note that ClientAuthentication does not return if frontend
+ * was rejected; it simply terminates this process.
+ */
+ frontend->protoVersion = sp->major;
+ frontend->database = strdup(sp->database);
+ if (frontend->database == NULL)
+ {
+ pool_error("do_child: strdup failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ frontend->username = strdup(sp->user);
+ if (frontend->username == NULL)
+ {
+ pool_error("do_child: strdup failed: %s\n", strerror(errno));
+ exit(1);
+ }
+ ClientAuthentication(frontend);
+ }
+
/*
* Ok, negotiaton with frontend has been done. Let's go to the next step.
*/
fd_set readmask;
int fds;
- struct sockaddr addr;
- socklen_t addrlen;
+ SockAddr saddr;
int fd = 0;
int afd;
int inet = 0;
* Note that some SysV systems do not work here. For those
* systems, we need some locking mechanism for the fd.
*/
- addrlen = sizeof(addr);
+ memset(&saddr, 0, sizeof(saddr));
+ saddr.salen = sizeof(saddr.addr);
#ifdef ACCEPT_PERFORMANCE
gettimeofday(&now1,0);
#endif
- afd = accept(fd, &addr, &addrlen);
+ afd = accept(fd, (struct sockaddr *)&saddr.addr, &saddr.salen);
if (afd < 0)
{
/*
set_ps_display("accept connection", false);
pool_debug("I am %d accept fd %d", getpid(), afd);
+ /* log who is connecting */
+ if (pool_config.log_connections)
+ {
+ char remote_host[NI_MAXHOST];
+ char remote_port[NI_MAXSERV];
+
+ remote_host[0] = '\0';
+ remote_port[0] = '\0';
+ if (getnameinfo_all(&saddr.addr, saddr.salen,
+ remote_host, sizeof(remote_host),
+ remote_port, sizeof(remote_port),
+ NI_NUMERICHOST | NI_NUMERICSERV))
+ {
+ int ret = getnameinfo_all(&saddr.addr, saddr.salen,
+ remote_host, sizeof(remote_host),
+ remote_port, sizeof(remote_port),
+ NI_NUMERICHOST | NI_NUMERICSERV);
+ if (ret)
+ pool_error("getnameinfo_all() failed: %s", gai_strerror(ret));
+ }
+ pool_log("connection received: host=%s%s%s",
+ remote_host, remote_port[0] ? " port=" : "", remote_port);
+ }
+
/* set NODELAY and KEEPALIVE options if INET connection */
if (inet)
{
close(afd);
return NULL;
}
+
+ /* save ip addres for hba */
+ memcpy(&cp->raddr, &saddr, sizeof(SockAddr));
+ if (cp->raddr.addr.ss_family == 0)
+ cp->raddr.addr.ss_family = AF_UNIX;
+
return cp;
}
/* config.h.in. Generated from configure.in by autoheader. */
+/* Define to the type of arg 1 of 'accept' */
+#undef ACCEPT_TYPE_ARG1
+
+/* Define to the type of arg 2 of 'accept' */
+#undef ACCEPT_TYPE_ARG2
+
+/* Define to the type of arg 3 of 'accept' */
+#undef ACCEPT_TYPE_ARG3
+
+/* Define to the return type of 'accept' */
+#undef ACCEPT_TYPE_RETURN
+
/* Define to 1 if you have the `asprintf' function. */
#undef HAVE_ASPRINTF
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
+/* Define to 1 if you have the `pam' library (-lpam). */
+#undef HAVE_LIBPAM
+
/* Define to 1 if you have the `PW' library (-lPW). */
#undef HAVE_LIBPW
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
/* Define to 1 if you have the <netinet/in.h> header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the <netinet/tcp.h> header file. */
#undef HAVE_NETINET_TCP_H
+/* Define to 1 if you have the <pam/pam_appl.h> header file. */
+#undef HAVE_PAM_PAM_APPL_H
+
+/* Define to 1 if you have the <security/pam_appl.h> header file. */
+#undef HAVE_SECURITY_PAM_APPL_H
+
/* Define to 1 if you have the `select' function. */
#undef HAVE_SELECT
/* Define to 1 if you have the `strtok' function. */
#undef HAVE_STRTOK
+/* Define to 1 if `sa_len' is member of `struct sockaddr'. */
+#undef HAVE_STRUCT_SOCKADDR_SA_LEN
+
+/* Define to 1 if the system has the type `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE
+
+/* Define to 1 if `ss_family' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+
+/* Define to 1 if `ss_len' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+
+/* Define to 1 if `__ss_family' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
+
+/* Define to 1 if `__ss_len' is member of `struct sockaddr_storage'. */
+#undef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+
/* Define to 1 if you have the <sys/param.h> header file. */
#undef HAVE_SYS_PARAM_H
/* Define to 1 if you have the <sys/pstat.h> header file. */
#undef HAVE_SYS_PSTAT_H
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
+/* Define to 1 if you have the <sys/un.h> header file. */
+#undef HAVE_SYS_UN_H
+
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
+/* Define to 1 to build with PAM support. (--with-pam) */
+#undef USE_PAM
+
/* Version number of package */
#undef VERSION
/^X\(\/\).*/{ s//\1/; q; }
s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
+ 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 ! -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; }; }
{ (exit 1); exit 1; }; }
fi
fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+(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%'`
--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
+ --with-pam build with PAM support
Some influential environment variables:
CC C compiler command
-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 sys/pstat.h
+
+
+
+for ac_header in fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h netdb.h sys/param.h sys/types.h sys/socket.h sys/un.h sys/time.h sys/pstat.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if eval "test \"\${$as_ac_Header+set}\" = set"; then
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 "$as_me:$LINENO: checking for struct sockaddr_storage" >&5
+echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6
+if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
-#include <signal.h>
-#ifdef signal
-# undef signal
-#endif
-#ifdef __cplusplus
-extern "C" void (*signal (int, void (*)(int)))(int);
-#else
-void (*signal ()) ();
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
#endif
+
int
main ()
{
-int i;
+if ((struct sockaddr_storage *) 0)
+ return 0;
+if (sizeof (struct sockaddr_storage))
+ return 0;
;
return 0;
}
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
- ac_cv_type_signal=void
+ ac_cv_type_struct_sockaddr_storage=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_type_signal=int
+ac_cv_type_struct_sockaddr_storage=no
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
+echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5
+echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6
+if test $ac_cv_type_struct_sockaddr_storage = yes; then
cat >>confdefs.h <<_ACEOF
-#define RETSIGTYPE $ac_cv_type_signal
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
_ACEOF
+fi
-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 "$as_me:$LINENO: checking for struct sockaddr_storage.ss_family" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.ss_family... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage_ss_family+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
#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;
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.ss_family)
+return 0;
;
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
+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
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
+ { 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_var=yes"
+ ac_cv_member_struct_sockaddr_storage_ss_family=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
+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 <limits.h> declares _doprnt.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define _doprnt innocuous__doprnt
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char _doprnt (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
#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;
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.ss_family)
+return 0;
;
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
+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
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
+ { 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_func__doprnt=yes
+ ac_cv_member_struct_sockaddr_storage_ss_family=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_func__doprnt=no
+ac_cv_member_struct_sockaddr_storage_ss_family=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext 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
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_family" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_family" >&6
+if test $ac_cv_member_struct_sockaddr_storage_ss_family = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_DOPRNT 1
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY 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 "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_family" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.__ss_family... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage___ss_family+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. */
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <sys/types.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <stdio.h>
-/* HP-UX has wait3 but does not fill in rusage at all. */
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
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);
- }
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.__ss_family)
+return 0;
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+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='./conftest$ac_exeext'
+ (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_func_wait3_rusage=yes
+ ac_cv_member_struct_sockaddr_storage___ss_family=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&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
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
_ACEOF
-
-fi
-
-
-
-
-
-
-
-
-
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
-for ac_func in setsid select socket sigprocmask strdup strerror strftime strtok asprintf setproctitle
-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
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.__ss_family)
+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_member_struct_sockaddr_storage___ss_family=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_storage___ss_family=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_family" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_family" >&6
+if test $ac_cv_member_struct_sockaddr_storage___ss_family = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY 1
+_ACEOF
+
+
+fi
+echo "$as_me:$LINENO: checking for struct sockaddr_storage.ss_len" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.ss_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage_ss_len+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
cat >conftest.$ac_ext <<_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
#endif
-#undef $ac_func
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
+int
+main ()
{
-#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
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.ss_len)
+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_member_struct_sockaddr_storage_ss_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
#endif
+
int
main ()
{
-return f != $ac_func;
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.ss_len)
+return 0;
;
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
+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
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
+ { 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_var=yes"
+ ac_cv_member_struct_sockaddr_storage_ss_len=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-eval "$as_ac_var=no"
+ac_cv_member_struct_sockaddr_storage_ss_len=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f conftest.err conftest.$ac_objext 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
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage_ss_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage_ss_len" >&6
+if test $ac_cv_member_struct_sockaddr_storage_ss_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
_ACEOF
+
fi
-done
+echo "$as_me:$LINENO: checking for struct sockaddr_storage.__ss_len" >&5
+echo $ECHO_N "checking for struct sockaddr_storage.__ss_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_storage___ss_len+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 <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
-PGSQL_INCLUDE_DIR=/usr/local/pgsql/include
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (ac_aggr.__ss_len)
+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_member_struct_sockaddr_storage___ss_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
-# Check whether --with-pgsql or --without-pgsql was given.
-if test "${with_pgsql+set}" = set; then
- withval="$with_pgsql"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
- 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;
+int
+main ()
+{
+static struct sockaddr_storage ac_aggr;
+if (sizeof ac_aggr.__ss_len)
+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_member_struct_sockaddr_storage___ss_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_storage___ss_len=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_storage___ss_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_storage___ss_len" >&6
+if test $ac_cv_member_struct_sockaddr_storage___ss_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN 1
+_ACEOF
+fi
+echo "$as_me:$LINENO: checking for struct sockaddr.sa_len" >&5
+echo $ECHO_N "checking for struct sockaddr.sa_len... $ECHO_C" >&6
+if test "${ac_cv_member_struct_sockaddr_sa_len+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 <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (ac_aggr.sa_len)
+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_member_struct_sockaddr_sa_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+
+
+int
+main ()
+{
+static struct sockaddr ac_aggr;
+if (sizeof ac_aggr.sa_len)
+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_member_struct_sockaddr_sa_len=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_member_struct_sockaddr_sa_len=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_sa_len" >&5
+echo "${ECHO_T}$ac_cv_member_struct_sockaddr_sa_len" >&6
+if test $ac_cv_member_struct_sockaddr_sa_len = yes; then
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_SOCKADDR_SA_LEN 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 <sys/types.h>
+#include <signal.h>
+#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 <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#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 <limits.h> declares _doprnt.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define _doprnt innocuous__doprnt
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#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 <sys/types.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <stdio.h>
+/* 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
+
+echo "$as_me:$LINENO: checking types of arguments for accept()" >&5
+echo $ECHO_N "checking types of arguments for accept()... $ECHO_C" >&6
+ if test "${ac_cv_func_accept_return+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "${ac_cv_func_accept_arg1+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "${ac_cv_func_accept_arg2+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test "${ac_cv_func_accept_arg3+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ for ac_cv_func_accept_return in 'int' 'unsigned int PASCAL'; do
+ for ac_cv_func_accept_arg1 in 'int' 'unsigned int'; do
+ for ac_cv_func_accept_arg2 in 'struct sockaddr *' 'const struct sockaddr *' 'void *'; do
+ for ac_cv_func_accept_arg3 in 'int' 'size_t' 'socklen_t' 'unsigned int' 'void'; do
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+extern $ac_cv_func_accept_return accept ($ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *);
+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_not_found=no; break 4
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_not_found=yes
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ done
+ done
+ done
+ done
+ if test "$ac_not_found" = yes; then
+ { { echo "$as_me:$LINENO: error: could not determine argument types" >&5
+echo "$as_me: error: could not determine argument types" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ if test "$ac_cv_func_accept_arg3" = "void"; then
+ ac_cv_func_accept_arg3=int
+ fi
+
+fi
+
+fi
+
+fi
+
+fi
+ echo "$as_me:$LINENO: result: $ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&5
+echo "${ECHO_T}$ac_cv_func_accept_return, $ac_cv_func_accept_arg1, $ac_cv_func_accept_arg2, $ac_cv_func_accept_arg3 *" >&6
+
+cat >>confdefs.h <<_ACEOF
+#define ACCEPT_TYPE_RETURN $ac_cv_func_accept_return
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ACCEPT_TYPE_ARG1 $ac_cv_func_accept_arg1
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ACCEPT_TYPE_ARG2 $ac_cv_func_accept_arg2
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define ACCEPT_TYPE_ARG3 $ac_cv_func_accept_arg3
+_ACEOF
+
+
+
+
+
+
+
+
+
+
+
+
+for ac_func in setsid select socket sigprocmask strdup strerror strftime strtok asprintf setproctitle
+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 <limits.h> declares $ac_func.
+ For example, HP-UX 11i <limits.h> 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 <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#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;
+
+
+
+
+# Check whether --with-pam or --without-pam was given.
+if test "${with_pam+set}" = set; then
+ withval="$with_pam"
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_PAM 1
+_ACEOF
+
+fi;
+if test "$with_pam" = yes ; then
+
+echo "$as_me:$LINENO: checking for pam_start in -lpam" >&5
+echo $ECHO_N "checking for pam_start in -lpam... $ECHO_C" >&6
+if test "${ac_cv_lib_pam_pam_start+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpam $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 pam_start ();
+int
+main ()
+{
+pam_start ();
+ ;
+ 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_pam_pam_start=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_pam_pam_start=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_pam_pam_start" >&5
+echo "${ECHO_T}$ac_cv_lib_pam_pam_start" >&6
+if test $ac_cv_lib_pam_pam_start = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPAM 1
+_ACEOF
+
+ LIBS="-lpam $LIBS"
+
+else
+ { { echo "$as_me:$LINENO: error: library 'pam' is required for PAM" >&5
+echo "$as_me: error: library 'pam' is required for PAM" >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+
+for ac_header in security/pam_appl.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
+
+else
+
+for ac_header in pam/pam_appl.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
+
+else
+ { { echo "$as_me:$LINENO: error: header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM." >&5
+echo "$as_me: error: header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+done
+
+fi
+
+done
+
+fi
ac_config_headers="$ac_config_headers config.h"
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 sys/pstat.h)
+AC_CHECK_HEADERS(fcntl.h unistd.h getopt.h netinet/tcp.h netinet/in.h netdb.h sys/param.h sys/types.h sys/socket.h sys/un.h sys/time.h sys/pstat.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_PID_T
AC_HEADER_TIME
+dnl Checks for sockadr_storage structure, members and necessary types
+AC_CHECK_TYPES([struct sockaddr_storage], [], [],
+[#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
+AC_CHECK_MEMBERS([struct sockaddr_storage.ss_family,
+ struct sockaddr_storage.__ss_family,
+ struct sockaddr_storage.ss_len,
+ struct sockaddr_storage.__ss_len,
+ struct sockaddr.sa_len], [], [],
+[#include <sys/types.h>
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+])
+
dnl Checks for library functions.
AC_TYPE_SIGNAL
AC_FUNC_VPRINTF
AC_FUNC_WAIT3
+AC_FUNC_ACCEPT_ARGTYPES
AC_CHECK_FUNCS(setsid select socket sigprocmask strdup strerror strftime strtok asprintf setproctitle)
PGSQL_INCLUDE_DIR=/usr/local/pgsql/include
AC_SUBST(PGSQL_INCLUDE_DIR)
+AC_ARG_WITH(pam,
+ [ --with-pam build with PAM support],
+ [AC_DEFINE([USE_PAM], 1, [Define to 1 to build with PAM support. (--with-pam)])])
+if test "$with_pam" = yes ; then
+ AC_CHECK_LIB(pam, pam_start, [], [AC_MSG_ERROR([library 'pam' is required for PAM])])
+ AC_CHECK_HEADERS(security/pam_appl.h, [],
+ [AC_CHECK_HEADERS(pam/pam_appl.h, [],
+ [AC_MSG_ERROR([header file <security/pam_appl.h> or <pam/pam_appl.h> is required for PAM.])])])
+fi
+
AM_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile)
{
int opt;
char conf_file[POOLMAXPATHLEN+1];
+ char hba_file[POOLMAXPATHLEN+1];
int i;
int pid;
myargv = argv;
snprintf(conf_file, sizeof(conf_file), "%s/%s", DEFAULT_CONFIGDIR, POOL_CONF_FILE_NAME);
+ snprintf(hba_file, sizeof(hba_file), "%s/%s", DEFAULT_CONFIGDIR, HBA_CONF_FILE_NAME);
- while ((opt = getopt(argc, argv, "df:hm:ns:")) != -1)
+ while ((opt = getopt(argc, argv, "a:df:hm:ns:")) != -1)
{
switch (opt)
{
+ case 'a': /* specify hba configuration file */
+ if (!optarg)
+ {
+ usage();
+ exit(1);
+ }
+ strncpy(hba_file, optarg, sizeof(hba_file));
+ break;
+
case 'd': /* debug option */
debug = 1;
break;
pool_debug("weight: %ld", weight_master);
+ /* read pool_hba.conf */
+ if (pool_config.enable_pool_hba)
+ load_hba(hba_file);
+
/*
* if a non-switch argument remains, then it should be either "stop" or "switch"
*/
{
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 [-f config_file][-a hba_file][-n][-d]\n");
+ fprintf(stderr, "usage: pgpool [-f config_file][-a hba_file] [-m {s[mart]|f[ast]|i[mmediate]}] stop\n");
+ fprintf(stderr, "usage: pgpool [-f config_file][-a hba_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, " hba_file default path: %s/%s\n",DEFAULT_CONFIGDIR, HBA_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");
# extra leading white space.
ignore_leading_white_space = false
+# - What to Log -
+
# If true, print all statements to the log. Like the log_statement option
# to PostgreSQL, this allows for observing queries without engaging in full
# debugging.
log_statement = false
+
+# If true, incoming connections will be printed to the log.
+log_connections = false
+
+# - HBA -
+
+# If true, use pool_hba.conf for client authentication. In pgpool 3.2,
+# the default value is false. This parameter is planned to be deleted
+# in pgpool 3.3, and pool_hba.conf will always be used.
+enable_pool_hba = false
#include "config.h"
#include "pool_signal.h"
+#include "pool_type.h"
+#include "pool_list.h"
#include <stdio.h>
#include <time.h>
-
-/* typdefs */
-#ifndef __cplusplus
-#ifndef bool
-typedef char bool;
-#endif
-
-#ifndef true
-#define true ((bool) 1)
-#endif
-
-#ifndef false
-#define false ((bool) 0)
-#endif
-
-#endif
+#include <netinet/in.h>
/* undef this if you have problems with non blocking accept() */
#define NONE_BLOCK
/* configuration file name */
#define POOL_CONF_FILE_NAME "pgpool.conf"
+#define HBA_CONF_FILE_NAME "pool_hba.conf"
/* pid file directory */
#define DEFAULT_LOGDIR "/tmp"
int num_servers; /* number of PostgreSQL servers */
int server_status[MAX_CONNECTION_SLOTS]; /* server status 0:unused, 1:up, 2:down */
int log_statement; /* 0:false, 1: true - logs all SQL statements */
+ int log_connections; /* 0:false, 1:true - logs incoming connections */
+ int enable_pool_hba; /* 0:false, 1:true - enables pool_hba.conf file authentication */
} POOL_CONFIG;
#define MAX_PASSWORD_SIZE 1024
int no_forward; /* if non 0, do not write to frontend */
+ /*
+ * frontend info needed for hba
+ */
+ int protoVersion;
+ SockAddr raddr;
+ UserAuth auth_method;
+ char *auth_arg;
+ char *database;
+ char *username;
+#ifdef USE_SSL
+ bool ssl;
+#endif
+
} POOL_CONNECTION;
/*
extern char **save_ps_display_args(int argc, char **argv);
extern void init_ps_display(const char *username, const char *dbname,
- const char *host_info, const char *initial_str);
+ const char *host_info, const char *initial_str);
extern void set_ps_display(const char *activity, bool force);
extern const char *get_ps_display(int *displen);
+/* pool_hba.c */
+extern void load_hba(char *hbapath);
+extern void ClientAuthentication(POOL_CONNECTION *frontend);
+
#endif /* POOL_H */
-/* A lexical scanner generated by flex */
-/* Scanner skeleton version:
- * $Header$
- */
+#line 3 "pool_config.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 33
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
#include <stdio.h>
-#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+#ifndef FLEXINT_H
+#define FLEXINT_H
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
#endif
+#endif /* ! FLEXINT_H */
#ifdef __cplusplus
-#include <stdlib.h>
-
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
-
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#if __STDC__
-#define YY_USE_PROTOS
#define YY_USE_CONST
#endif /* __STDC__ */
#endif /* ! __cplusplus */
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#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
* but we do it the disgusting crufty way forced on us by the ()-less
* definition of BEGIN.
*/
-#define BEGIN yy_start = 1 + 2 *
+#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 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_NEW_FILE yyrestart(yyin )
#define YY_END_OF_BUFFER_CHAR 0
/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
#define YY_BUF_SIZE 16384
+#endif
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
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 YY_LESS_LINENO(n)
+
+/* 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; \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
YY_RESTORE_YY_MORE_OFFSET \
- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
YY_DO_BEFORE_ACTION; /* set up yytext again */ \
} \
while ( 0 )
-#define unput(c) yyunput( c, yytext_ptr )
+#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;
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef unsigned int yy_size_t;
+#endif
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
struct yy_buffer_state
{
FILE *yy_input_file;
*/
int yy_at_bol;
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
/* 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
* just pointing yyin at a new input file.
*/
#define YY_BUFFER_EOF_PENDING 2
+
};
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
-static YY_BUFFER_STATE yy_current_buffer = 0;
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
/* 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".
+ *
+ * Returns the top of the stack, or NULL.
*/
-#define YY_CURRENT_BUFFER yy_current_buffer
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
/* 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_init = 0; /* 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
*/
static int yy_did_buffer_switch_on_eof;
-void yyrestart YY_PROTO(( FILE *input_file ));
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *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 )
+#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 ));
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (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 * ));
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (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; \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->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; \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
}
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+/* Begin user sect3 */
-#define yywrap() 1
+#define yywrap(n) 1
#define YY_SKIP_YYWRAP
+
typedef unsigned char YY_CHAR;
+
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
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[] ));
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (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; \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
*yy_cp = '\0'; \
- yy_c_buf_p = yy_cp;
+ (yy_c_buf_p) = yy_cp;
#define YY_NUM_RULES 11
#define YY_END_OF_BUFFER 12
-static yyconst short int yy_accept[38] =
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[38] =
{ 0,
0, 0, 12, 10, 2, 1, 10, 10, 10, 8,
7, 7, 9, 4, 2, 0, 3, 0, 5, 0,
5, 0, 0, 8, 7, 6, 0
} ;
-static yyconst int yy_ec[256] =
+static yyconst flex_int32_t yy_ec[256] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1,
15, 15, 15, 15, 15
} ;
-static yyconst int yy_meta[19] =
+static yyconst flex_int32_t 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] =
+static yyconst flex_int16_t yy_base[45] =
{ 0,
0, 0, 61, 86, 58, 86, 55, 14, 23, 43,
10, 46, 86, 28, 47, 40, 86, 16, 86, 22,
70, 75, 77, 80
} ;
-static yyconst short int yy_def[45] =
+static yyconst flex_int16_t yy_def[45] =
{ 0,
37, 1, 37, 37, 37, 37, 38, 39, 37, 40,
9, 9, 37, 41, 37, 38, 37, 39, 37, 42,
37, 37, 37, 37
} ;
-static yyconst short int yy_nxt[105] =
+static yyconst flex_int16_t yy_nxt[105] =
{ 0,
4, 5, 6, 7, 8, 9, 9, 10, 4, 11,
12, 13, 14, 14, 14, 4, 14, 14, 19, 23,
37, 37, 37, 37
} ;
-static yyconst short int yy_chk[105] =
+static yyconst flex_int16_t yy_chk[105] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 8, 11,
static yy_state_type yy_last_accepting_state;
static char *yy_last_accepting_cpos;
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
/* The intent behind this definition is that it'll catch
* any uses of REJECT which flex missed.
*/
#define YY_RESTORE_YY_MORE_OFFSET
char *yytext;
#line 1 "pool_config.l"
-#define INITIAL 0
/* -*-pgsql-c-*- */
/*
*
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"
+#line 541 "pool_config.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
/* 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 ));
+extern "C" int yywrap (void );
#else
-extern int yywrap YY_PROTO(( void ));
-#endif
+extern int yywrap (void );
#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 ));
+static void yy_flex_strncpy (char *,yyconst char *,int );
#endif
#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
+static int yy_flex_strlen (yyconst char * );
#endif
#ifndef YY_NO_INPUT
+
#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
+static int yyinput (void );
#else
-static int input YY_PROTO(( void ));
-#endif
+static int input (void );
#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 <stdlib.h>
-#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. */
#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().
*/
#ifndef YY_INPUT
#define YY_INPUT(buf,result,max_size) \
- if ( yy_current_buffer->yy_is_interactive ) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
{ \
- int c = '*', n; \
+ int c = '*'; \
+ size_t n; \
for ( n = 0; n < max_size && \
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \
buf[n] = (char) c; \
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" );
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
#endif
/* No semi-colon after return; correct usage is to write "yyterminate();" -
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
#endif
+/* end tables serialization structures and prototypes */
+
/* 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
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
/* Code executed at the beginning of each rule, after yytext and yyleng
* have been set up.
#define YY_RULE_SETUP \
YY_USER_ACTION
+/** The main scanner function which does all the work.
+ */
YY_DECL
- {
+{
register yy_state_type yy_current_state;
- register char *yy_cp = NULL, *yy_bp = NULL;
+ register char *yy_cp, *yy_bp;
register int yy_act;
-
+
#line 77 "pool_config.l"
-#line 607 "pool_config.c"
+#line 695 "pool_config.c"
- if ( yy_init )
+ if ( !(yy_init) )
{
- yy_init = 0;
+ (yy_init) = 1;
#ifdef YY_USER_INIT
YY_USER_INIT;
#endif
- if ( ! yy_start )
- yy_start = 1; /* first start state */
+ 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 );
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
- yy_load_buffer_state();
+ yy_load_buffer_state( );
}
while ( 1 ) /* loops until end-of-file is reached */
{
- yy_cp = yy_c_buf_p;
+ yy_cp = (yy_c_buf_p);
/* Support of yytext. */
- *yy_cp = yy_hold_char;
+ *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_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;
+ (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 = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 86 );
+ while ( yy_current_state != 37 );
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
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;
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
goto yy_find_action;
case 1:
+/* rule 1 can match eol */
YY_RULE_SETUP
#line 79 "pool_config.l"
Lineno++; return POOL_EOL;
/* 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_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"
#line 92 "pool_config.l"
ECHO;
YY_BREAK
-#line 748 "pool_config.c"
+#line 833 "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;
+ 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_cp = (yy_hold_char);
YY_RESTORE_YY_MORE_OFFSET
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
+ if ( YY_CURRENT_BUFFER_LVALUE->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
+ * 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;
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
}
/* Note that here we test for yy_c_buf_p "<=" to the position
* 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] )
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->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_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
/* Okay, we're now positioned to make the NUL
* transition. We couldn't have
yy_next_state = yy_try_NUL_trans( yy_current_state );
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
if ( yy_next_state )
{
/* Consume the NUL. */
- yy_cp = ++yy_c_buf_p;
+ yy_cp = ++(yy_c_buf_p);
yy_current_state = yy_next_state;
goto yy_match;
}
else
{
- yy_cp = yy_c_buf_p;
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
goto yy_find_action;
}
}
- else switch ( yy_get_next_buffer() )
+ else switch ( yy_get_next_buffer( ) )
{
case EOB_ACT_END_OF_FILE:
{
- yy_did_buffer_switch_on_eof = 0;
+ (yy_did_buffer_switch_on_eof) = 0;
- if ( yywrap() )
+ if ( yywrap( ) )
{
/* Note: because we've taken care in
* yy_get_next_buffer() to have set up
* YY_NULL, it'll still work - another
* YY_NULL will get returned.
*/
- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
+ (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 )
+ 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_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ 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_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
- yy_current_state = yy_get_previous_state();
+ yy_current_state = yy_get_previous_state( );
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
goto yy_find_action;
}
break;
"fatal flex scanner internal error--no action found" );
} /* end of action switch */
} /* end of scanning one token */
- } /* end of yylex */
-
+} /* end of yylex */
/* yy_get_next_buffer - try to read in a new buffer
*
* 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;
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->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] )
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->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 )
+ if ( YY_CURRENT_BUFFER_LVALUE->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 )
+ 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.
/* Try to read more data. */
/* First move last chars to start of buffer. */
- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
+ 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 )
+ if ( YY_CURRENT_BUFFER_LVALUE->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;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
else
{
- int num_to_read =
- yy_current_buffer->yy_buf_size - number_to_move - 1;
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->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;
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
int yy_c_buf_p_offset =
- (int) (yy_c_buf_p - b->yy_ch_buf);
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
if ( b->yy_is_our_buffer )
{
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 );
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
}
else
/* Can't grow it, we don't own it. */
YY_FATAL_ERROR(
"fatal error - scanner input buffer overflow" );
- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
- num_to_read = yy_current_buffer->yy_buf_size -
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->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_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
- yy_current_buffer->yy_n_chars = yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
- if ( yy_n_chars == 0 )
+ if ( (yy_n_chars) == 0 )
{
if ( number_to_move == YY_MORE_ADJ )
{
ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
+ yyrestart(yyin );
}
else
{
ret_val = EOB_ACT_LAST_MATCH;
- yy_current_buffer->yy_buffer_status =
+ YY_CURRENT_BUFFER_LVALUE->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;
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
- yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->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()
- {
+ static yy_state_type yy_get_previous_state (void)
+{
register yy_state_type yy_current_state;
register char *yy_cp;
+
+ yy_current_state = (yy_start);
- yy_current_state = yy_start;
-
- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
+ 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;
+ (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 )
{
}
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
- {
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
register int yy_is_jam;
- register char *yy_cp = yy_c_buf_p;
+ 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;
+ (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_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 */
-
+}
#ifndef YY_NO_INPUT
#ifdef __cplusplus
-static int yyinput()
+ static int yyinput (void)
#else
-static int input()
+ static int input (void)
#endif
- {
- int c;
- *yy_c_buf_p = yy_hold_char;
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
- if ( *yy_c_buf_p == YY_END_OF_BUFFER_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] )
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
/* This was really a NUL. */
- *yy_c_buf_p = '\0';
+ *(yy_c_buf_p) = '\0';
else
{ /* need more input */
- int offset = yy_c_buf_p - yytext_ptr;
- ++yy_c_buf_p;
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
- switch ( yy_get_next_buffer() )
+ switch ( yy_get_next_buffer( ) )
{
case EOB_ACT_LAST_MATCH:
/* This happens because yy_g_n_b()
*/
/* Reset buffer status. */
- yyrestart( yyin );
+ yyrestart(yyin );
- /* fall through */
+ /*FALLTHROUGH*/
case EOB_ACT_END_OF_FILE:
{
- if ( yywrap() )
+ if ( yywrap( ) )
return EOF;
- if ( ! yy_did_buffer_switch_on_eof )
+ if ( ! (yy_did_buffer_switch_on_eof) )
YY_NEW_FILE;
#ifdef __cplusplus
return yyinput();
}
case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p = yytext_ptr + offset;
+ (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;
-
+ 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;
- }
-#endif /* YY_NO_INPUT */
-
-#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 );
+}
+#endif /* ifndef YY_NO_INPUT */
- yy_init_buffer( yy_current_buffer, input_file );
- yy_load_buffer_state();
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ 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 )
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
return;
- if ( yy_current_buffer )
+ 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_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
}
- yy_current_buffer = new_buffer;
- yy_load_buffer_state();
+ YY_CURRENT_BUFFER_LVALUE = 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;
- }
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->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
- {
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
/* 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 );
+ b->yy_ch_buf = (char *) yyalloc(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 );
+ 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
- {
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
if ( ! b )
return;
- if ( b == yy_current_buffer )
- yy_current_buffer = (YY_BUFFER_STATE) 0;
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
if ( b->yy_is_our_buffer )
- yy_flex_free( (void *) b->yy_ch_buf );
-
- yy_flex_free( (void *) b );
- }
-
+ yyfree((void *) b->yy_ch_buf );
+ yyfree((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
-
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
- {
- yy_flush_buffer( b );
+{
+ int oerrno = errno;
+
+ 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 is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
- {
- if ( ! b )
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
return;
b->yy_n_chars = 0;
b->yy_at_bol = 1;
b->yy_buffer_status = YY_BUFFER_NEW;
- if ( b == yy_current_buffer )
- yy_load_buffer_state();
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
}
+}
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
-#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 ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ 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 ) );
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
if ( ! b )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
b->yy_fill_buffer = 0;
b->yy_buffer_status = YY_BUFFER_NEW;
- yy_switch_to_buffer( b );
+ 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
+}
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param str a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
-#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
- {
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
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 );
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
if ( ! buf )
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
- b = yy_scan_buffer( buf, n );
+ b = yy_scan_buffer(buf,n );
if ( ! b )
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
b->yy_is_our_buffer = 1;
return b;
- }
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
#endif
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
-#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;
+/* Redefine yyless() so it works in section 3 code. */
- yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yy_start_stack_depth * sizeof( int );
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
- if ( ! yy_start_stack )
- yy_start_stack = (int *) yy_flex_alloc( new_size );
+/* Accessor methods (get/set functions) to struct members. */
- else
- yy_start_stack = (int *) yy_flex_realloc(
- (void *) yy_start_stack, new_size );
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
- if ( ! yy_start_stack )
- YY_FATAL_ERROR(
- "out of memory expanding start-condition stack" );
- }
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
- yy_start_stack[yy_start_stack_ptr++] = YY_START;
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
- BEGIN(new_state);
- }
-#endif
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+/** Get the current token.
+ *
+ */
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
- {
- if ( --yy_start_stack_ptr < 0 )
- YY_FATAL_ERROR( "start-condition stack underflow" );
+char *yyget_text (void)
+{
+ return yytext;
+}
- BEGIN(yy_start_stack[yy_start_stack_ptr]);
- }
-#endif
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
- {
- return yy_start_stack[yy_start_stack_ptr - 1];
- }
-#endif
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
#else
-static void yy_fatal_error( msg )
-char msg[];
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
#endif
- {
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
- }
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
-/* Redefine yyless() so it works in section 3 code. */
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
-#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 )
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+ return 0;
+}
-/* Internal utility routines. */
+/*
+ * 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
- {
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
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
- {
+static int yy_flex_strlen (yyconst char * s )
+{
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
- {
+void *yyalloc (yy_size_t size )
+{
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
- {
+void *yyrealloc (void * ptr, yy_size_t size )
+{
/* 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
* 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 );
- }
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
-#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)
pool_config.insert_lock = 0;
pool_config.num_servers = 0;
pool_config.log_statement = 0;
+ pool_config.log_connections = 0;
+ pool_config.enable_pool_hba = 0;
#define PARSE_ERROR() pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext)
/* open config file */
}
pool_config.log_statement = v;
}
+ else if (!strcmp(key, "log_connections"))
+ {
+ int v = eval_logical(yytext);
+
+ if (v < 0)
+ {
+ pool_error("pool_config: invalid value %s for %s", yytext, key);
+ return(-1);
+ }
+ pool_config.log_connections = v;
+ }
+ else if (!strcmp(key, "enable_pool_hba"))
+ {
+ int v = eval_logical(yytext);
+
+ if (v < 0)
+ {
+ pool_error("pool_config: invalid value %s for %s", yytext, key);
+ return(-1);
+ }
+ pool_config.enable_pool_hba = v;
+ }
}
if (pool_config.backend_port)
}
return tokens;
}
+
pool_config.insert_lock = 0;
pool_config.num_servers = 0;
pool_config.log_statement = 0;
+ pool_config.log_connections = 0;
+ pool_config.enable_pool_hba = 0;
#define PARSE_ERROR() pool_error("pool_config: parse error at line %d '%s'", Lineno, yytext)
/* open config file */
}
pool_config.log_statement = v;
}
+ else if (!strcmp(key, "log_connections"))
+ {
+ int v = eval_logical(yytext);
+
+ if (v < 0)
+ {
+ pool_error("pool_config: invalid value %s for %s", yytext, key);
+ return(-1);
+ }
+ pool_config.log_connections = v;
+ }
+ else if (!strcmp(key, "enable_pool_hba"))
+ {
+ int v = eval_logical(yytext);
+
+ if (v < 0)
+ {
+ pool_error("pool_config: invalid value %s for %s", yytext, key);
+ return(-1);
+ }
+ pool_config.enable_pool_hba = v;
+ }
}
if (pool_config.backend_port)
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007 PgPool Global Development Group
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California *
+ * 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_hba.c.: Routines to handle host based authentication.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <netdb.h>
+
+#include "pool.h"
+#include "pool_path.h"
+#include "pool_ip.h"
+
+#define MULTI_VALUE_SEP "\001" /* delimiter for multi-valued column strings */
+#define MAX_TOKEN 256
+
+static List *hba_lines = NIL;
+static List *hba_line_nums = NIL;
+static char *hbaFileName;
+
+static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq);
+static void auth_failed(POOL_CONNECTION *frontend);
+static void close_all_backend_connections(void);
+static bool hba_getauthmethod(POOL_CONNECTION *frontend);
+static bool check_hba(POOL_CONNECTION *frontend);
+static void parse_hba(List *line, int line_num, POOL_CONNECTION *frontend, bool *found_p, bool *error_p);
+static void parse_hba_auth(ListCell **line_item, UserAuth *userauth_p, char **auth_arg_p, bool *error_p);
+static bool check_user(char *user, char *param_str);
+static bool check_db(char *dbname, char *user, char *param_str);
+static void free_lines(List **lines, List **line_nums);
+static void tokenize_file(const char *filename, FILE *file, List **lines, List **line_nums);
+static char *tokenize_inc_file(const char *outer_filename, const char *inc_filename);
+static bool pg_isblank(const char c);
+static void next_token(FILE *fp, char *buf, int bufsz);
+static char * next_token_expand(const char *filename, FILE *file);
+
+#ifdef USE_PAM
+#ifdef HAVE_PAM_PAM_APPL_H
+#include <pam/pam_appl.h>
+#endif
+#ifdef HAVE_SECURITY_PAM_APPL_H
+#include <security/pam_appl.h>
+#endif
+
+#define PGPOOL_PAM_SERVICE "pgpool" /* Service name passed to PAM */
+
+static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password);
+static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg, struct pam_response ** resp, void *appdata_ptr);
+/*
+ * recv_password_packet is usually used with authentications that require a client
+ * password. However, pgpool's hba function only uses it for PAM authentication,
+ * so declare a prototype here in "#ifdef USE_PAM" to avoid compilation warning.
+ */
+static char *recv_password_packet(POOL_CONNECTION *frontend);
+
+static struct pam_conv pam_passw_conv = {
+ &pam_passwd_conv_proc,
+ NULL
+};
+
+static char *pam_passwd = NULL; /* Workaround for Solaris 2.6 brokenness */
+static POOL_CONNECTION *pam_frontend_kludge; /* Workaround for passing
+ * POOL_CONNECTION *frontend
+ * into pam_passwd_conv_proc */
+#endif /* USE_PAM */
+
+
+/*
+ * read in hba config file
+ */
+void load_hba(char *hbapath)
+{
+ FILE *file;
+
+ if (hba_lines || hba_line_nums)
+ free_lines(&hba_lines, &hba_line_nums);
+
+ file = fopen(hbapath, "r");
+ if (!file)
+ {
+ pool_error("could not open \"%s\". reason: %s",
+ hbapath, strerror(errno));
+ exit(1);
+ }
+
+ pool_debug("loading \"%s\" for client authentication configuration file",
+ hbapath);
+
+ tokenize_file(hbapath, file, &hba_lines, &hba_line_nums);
+ fclose(file);
+
+ hbaFileName = strdup(hbapath);
+ if (hbaFileName == NULL)
+ {
+ pool_error("load_hba: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+}
+
+
+/*
+ * do frontend <-> pgpool authentication based on pool_hba.conf
+ */
+void ClientAuthentication(POOL_CONNECTION *frontend)
+{
+ POOL_STATUS status = POOL_ERROR;
+
+ if (! hba_getauthmethod(frontend))
+ {
+ pool_error("missing or erroneous pool_hba.conf file");
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000",
+ "missing or erroneous pool_hba.conf file", "",
+ "See pgpool log for details.", __FILE__, __LINE__);
+ close_all_backend_connections();
+ /*
+ * use exit(2) since this is not so fatal. other entries in
+ * pool_hba.conf may be valid, so treat it as reject.
+ */
+ exit(2);
+ }
+
+ switch (frontend->auth_method)
+ {
+ case uaReject:
+ {
+ /*
+ * This could have come from an explicit "reject" entry in
+ * pool_hba.conf, but more likely it means there was no matching
+ * entry. Take pity on the poor user and issue a helpful
+ * error message. NOTE: this is not a security breach,
+ * because all the info reported here is known at the frontend
+ * and must be assumed known to bad guys. We're merely helping
+ * out the less clueful good guys.
+ */
+ char hostinfo[NI_MAXHOST];
+ char *errmessage;
+ int messagelen;
+
+ getnameinfo_all(&frontend->raddr.addr, frontend->raddr.salen,
+ hostinfo, sizeof(hostinfo),
+ NULL, 0,
+ NI_NUMERICHOST);
+
+ messagelen = sizeof(hostinfo) +
+ strlen(frontend->username) + strlen(frontend->database) + 80;
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
+ {
+ pool_error("ClientAuthentication: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+
+#ifdef USE_SSL
+ snprintf(errmessage, messagelen+7, /* +7 is for "SSL off" */
+ "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\", %s",
+ hostinfo, frontend->username, frontend->database,
+ frontend->ssl ? "SSL on" : "SSL off");
+#else
+ snprintf(errmessage, messagelen,
+ "no pool_hba.conf entry for host \"%s\", user \"%s\", database \"%s\"",
+ hostinfo, frontend->username, frontend->database);
+#endif
+ pool_error(errmessage);
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000", errmessage,
+ "", "", __FILE__, __LINE__);
+
+ free(errmessage);
+ break;
+ }
+
+/* case uaKrb4: */
+/* break; */
+
+/* case uaKrb5: */
+/* break; */
+
+/* case uaIdent: */
+/* break; */
+
+/* case uaMD5: */
+/* break; */
+
+/* case uaCrypt: */
+/* break; */
+
+/* case uaPassword: */
+/* break; */
+
+#ifdef USE_PAM
+ case uaPAM:
+ pam_frontend_kludge = frontend;
+ status = CheckPAMAuth(frontend, frontend->username, "");
+ break;
+#endif /* USE_PAM */
+
+ case uaTrust:
+ status = POOL_CONTINUE;
+ break;
+ }
+
+ if (status == POOL_CONTINUE)
+ sendAuthRequest(frontend, AUTH_REQ_OK);
+ else if (status != POOL_CONTINUE)
+ auth_failed(frontend);
+}
+
+
+static void sendAuthRequest(POOL_CONNECTION *frontend, AuthRequest areq)
+{
+ int wsize; /* number of bytes to write */
+ int areq_nbo; /* areq in network byte order */
+
+ /*
+ * If AUTH_REQ_OK, then frontend is OK to connect __with_pgpool__.
+ * Do not send 'R' to the frontend, he still needs to authenticate
+ * himself with the backend.
+ */
+ if (areq == AUTH_REQ_OK)
+ return;
+
+ /* request a password */
+ pool_write(frontend, "R", 1);
+
+ if (frontend->protoVersion == PROTO_MAJOR_V3)
+ {
+/* if (areq == AUTH_REQ_MD5) */
+/* wsize = htonl(sizeof(int)*2+4); */
+/* else if (areq == AUTH_REQ_CRYPT) */
+/* wsize = htonl(sizeof(int)*2+2); */
+/* else */
+ wsize = htonl(sizeof(int)*2);
+ pool_write(frontend, &wsize, sizeof(int));
+ }
+
+ areq_nbo = htonl(areq);
+ pool_write(frontend, &areq_nbo, sizeof(int));
+
+ /* Add the salt for encrypted passwords. */
+/* if (areq == AUTH_REQ_MD5) */
+/* pq_sendbytes(&buf, port->md5Salt, 4); */
+/* else if (areq == AUTH_REQ_CRYPT) */
+/* pq_sendbytes(&buf, port->cryptSalt, 2); */
+
+ pool_flush(frontend);
+}
+
+
+#ifdef USE_PAM /* see the prototype comment */
+
+/*
+ * Collect password response packet from frontend.
+ *
+ * Returns NULL if couldn't get password, else malloc'd string.
+ */
+static char *recv_password_packet(POOL_CONNECTION *frontend)
+{
+ int rsize;
+ char *passwd;
+ char *returnVal;
+
+ if (frontend->protoVersion == PROTO_MAJOR_V3)
+ {
+ /* Expect 'p' message type */
+ char kind;
+
+ if (pool_read(frontend, &kind, 1) < 0)
+ return NULL;
+
+ if (kind != 'p')
+ {
+ pool_error("expected password response, got message type %c",
+ kind);
+ return NULL; /* bad message type */
+ }
+ }
+ /* pre-3.0 protocol does not send a message type */
+
+ if (pool_read(frontend, &rsize, sizeof(int)) < 0)
+ return NULL;
+
+ rsize = ntohl(rsize) - 4;
+ passwd = pool_read2(frontend, rsize); /* retrieve password */
+ if (passwd == NULL)
+ return NULL;
+
+ /* Do not echo password to logs, for security. */
+ pool_debug("received password packet from frontend for pgpool's HBA");
+
+ /*
+ * Return the received string. Note we do not attempt to do any
+ * character-set conversion on it; since we don't yet know the
+ * client's encoding, there wouldn't be much point.
+ */
+ returnVal = strdup(passwd);
+ if (returnVal == NULL)
+ {
+ pool_error("recv_password_packet: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ return returnVal;
+}
+
+#endif /* USE_PAM */
+
+/*
+ * Tell the user the authentication failed.
+ */
+static void auth_failed(POOL_CONNECTION *frontend)
+{
+ bool send_error_to_frontend = true;
+ int messagelen;
+ char *errmessage;
+
+ messagelen = strlen(frontend->username) + 100;
+ if ((errmessage = (char *)malloc(messagelen+1)) == NULL)
+ {
+ pool_error("auth_failed: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+
+ switch (frontend->auth_method)
+ {
+ case uaReject:
+ snprintf(errmessage, messagelen,
+ "authentication with pgpool failed for user \"%s\": host rejected",
+ frontend->username);
+ /*
+ * if uaReject, frontend should have received 'E' and disconnected already.
+ */
+ send_error_to_frontend = false;
+ break;
+/* case uaKrb4: */
+/* snprintf(errmessage, messagelen, */
+/* "Kerberos 4 authentication with pgpool failed for user \"%s\"", */
+/* frontend->username); */
+/* break; */
+/* case uaKrb5: */
+/* snprintf(errmessage, messagelen, */
+/* "Kerberos 5 authentication with pgpool failed for user \"%s\"", */
+/* frontend->username); */
+/* break; */
+ case uaTrust:
+ snprintf(errmessage, messagelen,
+ "\"trust\" authentication with pgpool failed for user \"%s\"",
+ frontend->username);
+ break;
+/* case uaIdent: */
+/* snprintf(errmessage, messagelen, */
+/* "Ident authentication with pgpool failed for user \"%s\"", */
+/* frontend->username); */
+/* break; */
+/* case uaMD5: */
+/* case uaCrypt: */
+/* case uaPassword: */
+/* snprintf(errmessage, messagelen, */
+/* "password authentication with pgpool failed for user \"%s\"", */
+/* frontend->username); */
+/* break; */
+#ifdef USE_PAM
+ case uaPAM:
+ snprintf(errmessage, messagelen,
+ "PAM authentication with pgpool failed for user \"%s\"",
+ frontend->username);
+ break;
+#endif /* USE_PAM */
+ default:
+ snprintf(errmessage, messagelen,
+ "authentication with pgpool failed for user \"%s\": invalid authentication method",
+ frontend->username);
+ break;
+ }
+
+ pool_error(errmessage);
+ if (send_error_to_frontend)
+ pool_send_error_message(frontend, frontend->protoVersion, "XX000", errmessage,
+ "", "", __FILE__, __LINE__);
+
+ /*
+ * don't need to free(errmessage). I will just kill myself.
+ */
+ close_all_backend_connections();
+ exit(2);
+}
+
+
+/*
+ * Close all of the cached backend connections.
+ *
+ * This is exactly the same as send_frontend_exits() in child.c.
+ */
+static void close_all_backend_connections(void)
+{
+ int i;
+ POOL_CONNECTION_POOL *p = pool_connection_pool;
+
+#ifdef HAVE_SIGPROCMASK
+ sigset_t oldmask;
+#else
+ int oldmask;
+#endif
+
+ POOL_SETMASK2(&BlockSig, &oldmask);
+
+ for (i=0;i<pool_config.max_pool;i++, p++)
+ {
+ if (!MASTER_CONNECTION(p))
+ continue;
+ if (MASTER_CONNECTION(p)->sp->user == NULL)
+ continue;
+ pool_send_frontend_exits(p);
+ }
+
+ POOL_SETMASK(&oldmask);
+}
+
+
+/*
+ * Determine what authentication method should be used when accessing database
+ * "database" from frontend "raddr", user "user". Return the method and
+ * an optional argument (stored in fields of *frontend), and true for success.
+ *
+ * Note that false indicates a problem with the hba config file.
+ * If the file is OK but does not contain any entry matching the request,
+ * we return true and method = uaReject.
+ */
+static bool hba_getauthmethod(POOL_CONNECTION *frontend)
+{
+ if (check_hba(frontend))
+ return true;
+ else
+ return false;
+}
+
+
+/*
+ * Scan the (pre-parsed) hba file line by line, looking for a match
+ * to the port's connection request.
+ */
+static bool check_hba(POOL_CONNECTION *frontend)
+{
+ bool found_entry = false;
+ bool error = false;
+ ListCell *line;
+ ListCell *line_num;
+
+ forboth(line, hba_lines, line_num, hba_line_nums)
+ {
+ parse_hba(lfirst(line), lfirst_int(line_num),
+ frontend, &found_entry, &error);
+ if (found_entry || error)
+ break;
+ }
+
+ if (!error)
+ {
+ /* If no matching entry was found, synthesize 'reject' entry. */
+ if (!found_entry)
+ frontend->auth_method = uaReject;
+ return true;
+ }
+ else
+ return false;
+}
+
+
+/*
+ * Process one line from the hba config file.
+ *
+ * See if it applies to a connection from a frontend with IP address
+ * frontend->raddr to a database named frontend->database. If so, return
+ * *found_p true and fill in the auth arguments into the appropriate
+ * frontend fields. If not, leave *found_p as it was. If the record has
+ * a syntax error, return *error_p true, after issuing a message to the
+ * log. If no error, leave *error_p as it was.
+ */
+static void parse_hba(List *line, int line_num, POOL_CONNECTION *frontend,
+ bool *found_p, bool *error_p)
+{
+ char *token;
+ char *db, *db_tmp;
+ char *user, *user_tmp;
+ struct addrinfo *gai_result;
+ struct addrinfo hints;
+ int ret;
+ struct sockaddr_storage addr;
+ struct sockaddr_storage mask;
+ char *cidr_slash;
+ ListCell *line_item;
+
+ line_item = list_head(line);
+ /* Check the record type. */
+ token = lfirst(line_item);
+ if (strcmp(token, "local") == 0)
+ {
+ /* Get the database. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ db = lfirst(line_item);
+
+ /* Get the user. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ user = lfirst(line_item);
+
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+
+ /* Read the rest of the line. */
+ parse_hba_auth(&line_item, &frontend->auth_method,
+ &frontend->auth_arg, error_p);
+ if (*error_p)
+ goto hba_syntax;
+
+ /* Disallow auth methods that always need TCP/IP sockets to work */
+ /*
+ if (frontend->auth_method == uaKrb4 ||
+ frontend->auth_method == uaKrb5)
+ goto hba_syntax;
+ */
+
+ /* Does not match if connection isn't AF_UNIX */
+ if (!IS_AF_UNIX(frontend->raddr.addr.ss_family))
+ return;
+ }
+ else if (strcmp(token, "host") == 0
+ || strcmp(token, "hostssl") == 0
+ || strcmp(token, "hostnossl") == 0)
+ {
+ if (token[4] == 's') /* "hostssl" */
+ {
+#ifdef USE_SSL
+ /* Record does not match if we are not on an SSL connection */
+ if (!frontend->ssl)
+ return;
+
+ /* Placeholder to require specific SSL level, perhaps? */
+ /* Or a client certificate */
+
+ /* Since we were on SSL, proceed as with normal 'host' mode */
+#else
+ /* We don't accept this keyword at all if no SSL support */
+ goto hba_syntax;
+#endif
+ }
+#ifdef USE_SSL
+ else if (token[4] == 'n') /* "hostnossl" */
+ {
+ /* Record does not match if we are on an SSL connection */
+ if (frontend->ssl)
+ return;
+ }
+#endif
+
+ /* Get the database. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ db = lfirst(line_item);
+
+ /* Get the user. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ user = lfirst(line_item);
+
+ /* Read the IP address field. (with or without CIDR netmask) */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ token = lfirst(line_item);
+
+ /* Check if it has a CIDR suffix and if so isolate it */
+ cidr_slash = strchr(token, '/');
+ if (cidr_slash)
+ *cidr_slash = '\0';
+
+ /* Get the IP address either way */
+ hints.ai_flags = AI_NUMERICHOST;
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = 0;
+ hints.ai_protocol = 0;
+ hints.ai_addrlen = 0;
+ hints.ai_canonname = NULL;
+ hints.ai_addr = NULL;
+ hints.ai_next = NULL;
+
+ ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
+ if (ret || !gai_result)
+ {
+ pool_log("invalid IP address \"%s\" in file \"%s\" line %d: %s",
+ token, hbaFileName, line_num, gai_strerror(ret));
+ if (cidr_slash)
+ *cidr_slash = '/';
+ if (gai_result)
+ freeaddrinfo_all(hints.ai_family, gai_result);
+ goto hba_other_error;
+ }
+
+ if (cidr_slash)
+ *cidr_slash = '/';
+
+ memcpy(&addr, gai_result->ai_addr, gai_result->ai_addrlen);
+ freeaddrinfo_all(hints.ai_family, gai_result);
+
+ /* Get the netmask */
+ if (cidr_slash)
+ {
+ if (SockAddr_cidr_mask(&mask, cidr_slash + 1, addr.ss_family) < 0)
+ goto hba_syntax;
+ }
+ else
+ {
+ /* Read the mask field. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ token = lfirst(line_item);
+
+ ret = getaddrinfo_all(token, NULL, &hints, &gai_result);
+ if (ret || !gai_result)
+ {
+ pool_log("invalid IP mask \"%s\" in file \"%s\" line %d: %s",
+ token, hbaFileName, line_num, gai_strerror(ret));
+ if (gai_result)
+ freeaddrinfo_all(hints.ai_family, gai_result);
+ goto hba_other_error;
+ }
+
+ memcpy(&mask, gai_result->ai_addr, gai_result->ai_addrlen);
+ freeaddrinfo_all(hints.ai_family, gai_result);
+
+ if (addr.ss_family != mask.ss_family)
+ {
+ pool_log("IP address and mask do not match in file \"%s\" line %d",
+ hbaFileName, line_num);
+ goto hba_other_error;
+ }
+ }
+
+ if (addr.ss_family != frontend->raddr.addr.ss_family)
+ {
+ /*
+ * Wrong address family. We allow only one case: if the file
+ * has IPv4 and the port is IPv6, promote the file address to
+ * IPv6 and try to match that way.
+ */
+#ifdef HAVE_IPV6
+ if (addr.ss_family == AF_INET && frontend->raddr.addr.ss_family == AF_INET6)
+ {
+ promote_v4_to_v6_addr(&addr);
+ promote_v4_to_v6_mask(&mask);
+ }
+ else
+#endif /* HAVE_IPV6 */
+ {
+ /* Line doesn't match client port, so ignore it. */
+ return;
+ }
+ }
+
+ /* Ignore line if client port is not in the matching addr range. */
+ if (!rangeSockAddr(&frontend->raddr.addr, &addr, &mask))
+ return;
+
+ /* Read the rest of the line. */
+ line_item = lnext(line_item);
+ if (!line_item)
+ goto hba_syntax;
+ parse_hba_auth(&line_item, &frontend->auth_method,
+ &frontend->auth_arg, error_p);
+ if (*error_p)
+ goto hba_syntax;
+ }
+ else
+ goto hba_syntax;
+
+ /* Does the entry match database and user? */
+ /*
+ * duplicate db and username since strtok() in check_db() and check_user()
+ * will override '\001' with '\0'.
+ */
+ db_tmp = strdup(db);
+ if (db_tmp == NULL)
+ {
+ pool_error("parse_hba: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ user_tmp = strdup(user);
+ if (user_tmp == NULL)
+ {
+ pool_error("parse_hba: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ if (!check_db(frontend->database, frontend->username, db_tmp))
+ return;
+ if (!check_user(frontend->username, user_tmp))
+ return;
+ free(db_tmp);
+ free(user_tmp);
+
+ /* Success */
+ *found_p = true;
+ return;
+
+ hba_syntax:
+ if (line_item)
+ pool_log("invalid entry in file \"%s\" at line %d, token \"%s\"",
+ hbaFileName, line_num, (char *) lfirst(line_item));
+ else
+ pool_log("missing field in file \"%s\" at end of line %d",
+ hbaFileName, line_num);
+
+ /* Come here if suitable message already logged */
+ hba_other_error:
+ *error_p = true;
+}
+
+
+/*
+ * Scan the rest of a host record (after the mask field)
+ * and return the interpretation of it as *userauth_p, *auth_arg_p, and
+ * *error_p. *line_item points to the next token of the line, and is
+ * advanced over successfully-read tokens.
+ */
+static void parse_hba_auth(ListCell **line_item, UserAuth *userauth_p,
+ char **auth_arg_p, bool *error_p)
+{
+ char *token;
+
+ *auth_arg_p = NULL;
+
+ if (!*line_item)
+ {
+ *error_p = true;
+ return;
+ }
+
+ token = lfirst(*line_item);
+ if (strcmp(token, "trust") == 0)
+ *userauth_p = uaTrust;
+ /*
+ else if (strcmp(token, "ident") == 0)
+ *userauth_p = uaIdent;
+ else if (strcmp(token, "password") == 0)
+ *userauth_p = uaPassword;
+ else if (strcmp(token, "krb4") == 0)
+ *userauth_p = uaKrb4;
+ else if (strcmp(token, "krb5") == 0)
+ *userauth_p = uaKrb5;
+ */
+ else if (strcmp(token, "reject") == 0)
+ *userauth_p = uaReject;
+ /*
+ else if (strcmp(token, "md5") == 0)
+ *userauth_p = uaMD5;
+ else if (strcmp(token, "crypt") == 0)
+ *userauth_p = uaCrypt;
+ */
+#ifdef USE_PAM
+ else if (strcmp(token, "pam") == 0)
+ *userauth_p = uaPAM;
+#endif /* USE_PAM */
+ else
+ {
+ *error_p = true;
+ return;
+ }
+ *line_item = lnext(*line_item);
+
+ /* Get the authentication argument token, if any */
+ if (*line_item)
+ {
+ token = lfirst(*line_item);
+ *auth_arg_p = strdup(token);
+ if (*auth_arg_p == NULL)
+ {
+ pool_error("parse_hba_auth: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ *line_item = lnext(*line_item);
+ /* If there is more on the line, it is an error */
+ if (*line_item)
+ *error_p = true;
+ }
+}
+
+
+/*
+ * Check comma user list for a specific user, handle group names.
+ */
+static bool check_user(char *user, char *param_str)
+{
+ char *tok;
+
+ for (tok = strtok(param_str, MULTI_VALUE_SEP);
+ tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
+ {
+ if (tok[0] == '+')
+ {
+ /*
+ * pgpool cannot accept groups. commented lines below are the
+ * original code.
+ */
+ pool_error("group token \"+\" is not supported in pgpool");
+ return false;
+/* if (check_group(tok + 1, user)) */
+/* return true; */
+ }
+ else if (strcmp(tok, user) == 0 || strcmp(tok, "all\n") == 0)
+ return true;
+ }
+
+ return false;
+}
+
+
+/*
+ * Check to see if db/user combination matches param string.
+ */
+static bool check_db(char *dbname, char *user, char *param_str)
+{
+ char *tok;
+
+ for (tok = strtok(param_str, MULTI_VALUE_SEP);
+ tok != NULL; tok = strtok(NULL, MULTI_VALUE_SEP))
+ {
+ if (strcmp(tok, "all\n") == 0)
+ return true;
+ else if (strcmp(tok, "sameuser\n") == 0)
+ {
+ if (strcmp(dbname, user) == 0)
+ return true;
+ }
+ else if (strcmp(tok, "samegroup\n") == 0)
+ {
+ /*
+ * pgpool cannot accept groups. commented lines below are the
+ * original code.
+ */
+ pool_error("group token \"samegroup\" is not supported in pgpool");
+ return false;
+/* if (check_group(dbname, user)) */
+/* return true; */
+ }
+ else if (strcmp(tok, dbname) == 0)
+ return true;
+ }
+
+ return false;
+}
+
+
+/*
+ * tokenize the given file, storing the resulting data into two lists:
+ * a list of sublists, each sublist containing the tokens in a line of
+ * the file, and a list of line numbers.
+ *
+ * filename must be the absolute path to the target file.
+ */
+static void tokenize_file(const char *filename, FILE *file,
+ List **lines, List **line_nums)
+{
+ List *current_line = NIL;
+ int line_number = 1;
+ char *buf;
+
+ *lines = *line_nums = NIL;
+
+ while (!feof(file))
+ {
+ buf = next_token_expand(filename, file);
+
+ /* add token to list, unless we are at EOL or comment start */
+ if (buf[0])
+ {
+ if (current_line == NIL)
+ {
+ /* make a new line List, record its line number */
+ current_line = lappend(current_line, buf);
+ *lines = lappend(*lines, current_line);
+ *line_nums = lappend_int(*line_nums, line_number);
+ }
+ else
+ {
+ /* append token to current line's list */
+ current_line = lappend(current_line, buf);
+ }
+ }
+ else
+ {
+ /* we are at real or logical EOL, so force a new line List */
+ current_line = NIL;
+ /* Advance line number whenever we reach EOL */
+ line_number++;
+ /* Don't forget to free the next_token_expand result */
+ free(buf);
+ }
+ }
+}
+
+
+static char * tokenize_inc_file(const char *outer_filename,
+ const char *inc_filename)
+{
+ char *inc_fullname;
+ FILE *inc_file;
+ List *inc_lines;
+ List *inc_line_nums;
+ ListCell *line;
+ char *comma_str;
+
+ if (is_absolute_path(inc_filename))
+ {
+ /* absolute path is taken as-is */
+ inc_fullname = strdup(inc_filename);
+ if (inc_fullname == NULL)
+ {
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ }
+ else
+ {
+ /* relative path is relative to dir of calling file */
+ inc_fullname = (char *)malloc(strlen(outer_filename) + 1 +
+ strlen(inc_filename) + 1);
+ if (inc_fullname == NULL)
+ {
+ pool_error("tokenize_inc_file: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ strcpy(inc_fullname, outer_filename);
+ get_parent_directory(inc_fullname);
+ join_path_components(inc_fullname, inc_fullname, inc_filename);
+ canonicalize_path(inc_fullname);
+ }
+
+ inc_file = fopen(inc_fullname, "r");
+ if (inc_file == NULL)
+ {
+ char *returnVal;
+
+ pool_error("could not open secondary authentication file \"@%s\" as \"%s\": reason: %s",
+ inc_filename, inc_fullname, strerror(errno));
+ free(inc_fullname);
+
+ /* return single space, it matches nothing */
+ returnVal = strdup(" ");
+ if (returnVal == NULL)
+ {
+ pool_error("tokenize_inc_file: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ return returnVal;
+ }
+
+ /* There is possible recursion here if the file contains @ */
+ tokenize_file(inc_fullname, inc_file, &inc_lines, &inc_line_nums);
+
+ /*FreeFile(inc_file);*/
+ fclose(inc_file);
+ free(inc_fullname);
+
+ /* Create comma-separated string from List */
+ comma_str = strdup("");
+ if (comma_str == NULL)
+ {
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ foreach(line, inc_lines)
+ {
+ List *token_list = (List *) lfirst(line);
+ ListCell *token;
+
+ foreach(token, token_list)
+ {
+ int oldlen = strlen(comma_str);
+ int needed;
+
+ needed = oldlen + strlen(lfirst(token)) + 1;
+ if (oldlen > 0)
+ needed++;
+ comma_str = realloc(comma_str, needed);
+ if (comma_str == NULL)
+ {
+ pool_error("tokenize_inc_file: realloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ if (oldlen > 0)
+ strcat(comma_str, MULTI_VALUE_SEP);
+ strcat(comma_str, lfirst(token));
+ }
+ }
+
+ free_lines(&inc_lines, &inc_line_nums);
+
+ /* if file is empty, return single space rather than empty string */
+ if (strlen(comma_str) == 0)
+ {
+ char *returnVal;
+
+ free(comma_str);
+ returnVal = strdup(" ");
+ if (returnVal == NULL)
+ {
+ pool_error("tokenize_inc_file: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ return returnVal;
+ }
+
+ return comma_str;
+}
+
+
+/*
+ * isblank() exists in the ISO C99 spec, but it's not very portable yet,
+ * so provide our own version.
+ */
+static bool pg_isblank(const char c)
+{
+ return c == ' ' || c == '\t' || c == '\r';
+}
+
+
+/*
+ * Tokenize file and handle file inclusion and comma lists. We have
+ * to break apart the commas to expand any file names then
+ * reconstruct with commas.
+ *
+ * The result is always a malloc'd string. If it's zero-length then
+ * we have reached EOL.
+ */
+static char * next_token_expand(const char *filename, FILE *file)
+{
+ char buf[MAX_TOKEN];
+ char *comma_str;
+ bool trailing_comma;
+ char *incbuf;
+ int needed;
+
+ comma_str = strdup("");
+ if (comma_str == NULL)
+ {
+ pool_error("next_token_expand: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+
+ do
+ {
+ next_token(file, buf, sizeof(buf));
+ if (!buf[0])
+ break;
+
+ if (buf[strlen(buf) - 1] == ',')
+ {
+ trailing_comma = true;
+ buf[strlen(buf) - 1] = '\0';
+ }
+ else
+ trailing_comma = false;
+
+ /* Is this referencing a file? */
+ if (buf[0] == '@')
+ incbuf = tokenize_inc_file(filename, buf + 1);
+ else
+ {
+ incbuf = strdup(buf);
+ if (incbuf == NULL)
+ {
+ pool_error("next_token_expand: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ }
+
+ needed = strlen(comma_str) + strlen(incbuf) + 1;
+ if (trailing_comma)
+ needed++;
+ comma_str = realloc(comma_str, needed);
+ if (comma_str == NULL)
+ {
+ pool_error("next_token_expand: realloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ strcat(comma_str, incbuf);
+ if (trailing_comma)
+ strcat(comma_str, MULTI_VALUE_SEP);
+ free(incbuf);
+ } while (trailing_comma);
+
+ return comma_str;
+}
+
+
+/*
+ * Grab one token out of fp. Tokens are strings of non-blank
+ * characters bounded by blank characters, beginning of line, and
+ * end of line. Blank means space or tab. Return the token as
+ * *buf. Leave file positioned at the character immediately after the
+ * token or EOF, whichever comes first. If no more tokens on line,
+ * return empty string as *buf and position the file to the beginning
+ * of the next line or EOF, whichever comes first. Allow spaces in
+ * quoted strings. Terminate on unquoted commas. Handle
+ * comments. Treat unquoted keywords that might be user names or
+ * database names specially, by appending a newline to them.
+ */
+static void next_token(FILE *fp, char *buf, int bufsz)
+{
+ int c;
+ char *start_buf = buf;
+ char *end_buf = buf + (bufsz - 2);
+ bool in_quote = false;
+ bool was_quote = false;
+ bool saw_quote = false;
+
+ /*Assert(end_buf > start_buf);*/
+
+ /* Move over initial whitespace and commas */
+ while ((c = getc(fp)) != EOF && (pg_isblank(c) || c == ','))
+ ;
+
+ if (c == EOF || c == '\n')
+ {
+ *buf = '\0';
+ return;
+ }
+
+ /*
+ * Build a token in buf of next characters up to EOF, EOL, unquoted
+ * comma, or unquoted whitespace.
+ */
+ while (c != EOF && c != '\n' &&
+ (!pg_isblank(c) || in_quote == true))
+ {
+ /* skip comments to EOL */
+ if (c == '#' && !in_quote)
+ {
+ while ((c = getc(fp)) != EOF && c != '\n')
+ ;
+ /* If only comment, consume EOL too; return EOL */
+ if (c != EOF && buf == start_buf)
+ c = getc(fp);
+ break;
+ }
+
+ if (buf >= end_buf)
+ {
+ *buf = '\0';
+ pool_log("authentication file token too long, skipping: \"%s\"", start_buf);
+ /* Discard remainder of line */
+ while ((c = getc(fp)) != EOF && c != '\n')
+ ;
+ break;
+ }
+
+ if (c != '"' || (c == '"' && was_quote))
+ *buf++ = c;
+
+ /* We pass back the comma so the caller knows there is more */
+ if ((pg_isblank(c) || c == ',') && !in_quote)
+ break;
+
+ /* Literal double-quote is two double-quotes */
+ if (in_quote && c == '"')
+ was_quote = !was_quote;
+ else
+ was_quote = false;
+
+ if (c == '"')
+ {
+ in_quote = !in_quote;
+ saw_quote = true;
+ }
+
+ c = getc(fp);
+ }
+
+ /*
+ * Put back the char right after the token (critical in case it is
+ * EOL, since we need to detect end-of-line at next call).
+ */
+ if (c != EOF)
+ ungetc(c, fp);
+
+ *buf = '\0';
+
+ if (!saw_quote &&
+ (strcmp(start_buf, "all") == 0 ||
+ strcmp(start_buf, "sameuser") == 0 ||
+ strcmp(start_buf, "samegroup") == 0))
+ {
+ /* append newline to a magical keyword */
+ *buf++ = '\n';
+ *buf = '\0';
+ }
+}
+
+
+/*
+ * free memory used by lines and tokens built by tokenize_file()
+ */
+static void free_lines(List **lines, List **line_nums)
+{
+ if (*lines)
+ {
+ ListCell *line;
+
+ foreach(line, *lines)
+ {
+ List *ln = lfirst(line);
+ ListCell *token;
+
+ foreach(token, ln)
+ free(lfirst(token));
+
+ list_free(ln);
+ }
+
+ list_free(*lines);
+ *lines = NIL;
+ }
+
+ if (*line_nums)
+ {
+ list_free(*line_nums);
+ *line_nums = NIL;
+ }
+}
+
+
+#ifdef USE_PAM
+
+/*
+ * PAM conversation function
+ */
+static int pam_passwd_conv_proc(int num_msg, const struct pam_message ** msg,
+ struct pam_response ** resp, void *appdata_ptr)
+{
+ if (num_msg != 1 || msg[0]->msg_style != PAM_PROMPT_ECHO_OFF)
+ {
+ switch (msg[0]->msg_style)
+ {
+ case PAM_ERROR_MSG:
+ pool_log("error from underlying PAM layer: %s",
+ msg[0]->msg);
+ return PAM_CONV_ERR;
+ default:
+ pool_log("unsupported PAM conversation %d/%s",
+ msg[0]->msg_style, msg[0]->msg);
+ return PAM_CONV_ERR;
+ }
+ }
+
+ if (!appdata_ptr)
+ {
+ /*
+ * Workaround for Solaris 2.6 where the PAM library is broken and
+ * does not pass appdata_ptr to the conversation routine
+ */
+ appdata_ptr = pam_passwd;
+ }
+
+ /*
+ * Password wasn't passed to PAM the first time around - let's go ask
+ * the client to send a password, which we then stuff into PAM.
+ */
+ if (strlen(appdata_ptr) == 0)
+ {
+ char *passwd;
+
+ sendAuthRequest(pam_frontend_kludge, AUTH_REQ_PASSWORD);
+ passwd = recv_password_packet(pam_frontend_kludge);
+
+ if (passwd == NULL)
+ return PAM_CONV_ERR; /* client didn't want to send password */
+
+ if (strlen(passwd) == 0)
+ {
+ pool_log("empty password returned by client");
+ return PAM_CONV_ERR;
+ }
+ appdata_ptr = passwd;
+ }
+
+ /*
+ * PAM will free this memory in * pam_end()
+ */
+ *resp = calloc(num_msg, sizeof(struct pam_response));
+ if (!*resp)
+ {
+ /* originally, it was logged as LOG */
+ pool_error("pam_passwd_conv_proc: calloc failed: %s", strerror(errno));
+ return PAM_CONV_ERR;
+ }
+
+ (*resp)[0].resp = strdup((char *) appdata_ptr);
+ if ((*resp)[0].resp == NULL)
+ {
+ pool_error("pam_passwd_conv_proc: strdup failed: %s", strerror(errno));
+ exit(1);
+ }
+ (*resp)[0].resp_retcode = 0;
+
+ return ((*resp)[0].resp ? PAM_SUCCESS : PAM_CONV_ERR);
+}
+
+
+/*
+ * Check authentication against PAM.
+ */
+static POOL_STATUS CheckPAMAuth(POOL_CONNECTION *frontend, char *user, char *password)
+{
+ int retval;
+ pam_handle_t *pamh = NULL;
+
+ /*
+ * Apparently, Solaris 2.6 is broken, and needs ugly static variable
+ * workaround
+ */
+ pam_passwd = password;
+
+ /*
+ * Set the application data portion of the conversation struct This is
+ * later used inside the PAM conversation to pass the password to the
+ * authentication module.
+ */
+ pam_passw_conv.appdata_ptr = (char *) password; /* from password above,
+ * not allocated */
+
+ /* Optionally, one can set the service name in pool_hba.conf */
+ if (frontend->auth_arg && frontend->auth_arg[0] != '\0')
+ retval = pam_start(frontend->auth_arg, "pgpool@",
+ &pam_passw_conv, &pamh);
+ else
+ retval = pam_start(PGPOOL_PAM_SERVICE, "pgpool@",
+ &pam_passw_conv, &pamh);
+
+ if (retval != PAM_SUCCESS)
+ {
+ pool_log("could not create PAM authenticator: %s",
+ pam_strerror(pamh, retval));
+ pam_passwd = NULL; /* Unset pam_passwd */
+ return POOL_ERROR;
+ }
+
+ retval = pam_set_item(pamh, PAM_USER, user);
+ if (retval != PAM_SUCCESS)
+ {
+ pool_log("pam_set_item(PAM_USER) failed: %s",
+ pam_strerror(pamh, retval));
+ pam_passwd = NULL; /* Unset pam_passwd */
+ return POOL_ERROR;
+ }
+
+ retval = pam_set_item(pamh, PAM_CONV, &pam_passw_conv);
+ if (retval != PAM_SUCCESS)
+ {
+ pool_log("pam_set_item(PAM_CONV) failed: %s",
+ pam_strerror(pamh, retval));
+ pam_passwd = NULL; /* Unset pam_passwd */
+ return POOL_ERROR;
+ }
+
+ retval = pam_authenticate(pamh, 0);
+ if (retval != PAM_SUCCESS) /* service name does not exist */
+ {
+ pool_log("pam_authenticate failed: %s",
+ pam_strerror(pamh, retval));
+ pam_passwd = NULL; /* Unset pam_passwd */
+ return POOL_ERROR;
+ }
+
+ retval = pam_acct_mgmt(pamh, 0);
+ if (retval != PAM_SUCCESS)
+ {
+ pool_log("pam_acct_mgmt failed: %s",
+ pam_strerror(pamh, retval));
+ pam_passwd = NULL; /* Unset pam_passwd */
+ return POOL_ERROR;
+ }
+
+ retval = pam_end(pamh, retval);
+ if (retval != PAM_SUCCESS)
+ {
+ pool_log("could not release PAM authenticator: %s",
+ pam_strerror(pamh, retval));
+ }
+
+ pam_passwd = NULL; /* Unset pam_passwd */
+
+ return (retval == PAM_SUCCESS ? POOL_CONTINUE : POOL_ERROR);
+}
+
+#endif /* USE_PAM */
--- /dev/null
+# pgpool Client Authentication Configuration File
+# ===============================================
+#
+# The format rule in this file follows the rules in the PostgreSQL
+# Administrator's Guide. Refer to chapter "Client Authentication" for a
+# complete description. A short synopsis follows.
+#
+# This file controls: which hosts are allowed to connect, how clients
+# are authenticated, which user names they can use, which databases they
+# can access. Records take one of these forms:
+#
+# local DATABASE USER METHOD [OPTION]
+# host DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+# hostnossl DATABASE USER CIDR-ADDRESS METHOD [OPTION]
+#
+# (The uppercase items must be replaced by actual values.)
+#
+# The first field is the connection type: "local" is a Unix-domain socket,
+# "host" is a plain TCP/IP socket since pgpool currently doest not support
+# SSL connection. "hostnossl" is also a plain TCP/IP socket.
+#
+# DATABASE can be "all", "sameuser", a database name, or a comma-separated
+# list thereof. Note that "samegroup" like in PostgreSQL's pg_hba.conf
+# file is not supported, since pgpool does not know which group a user
+# belongs to. Also note that the database specified here may not exist in
+# the backend PostgreSQL. pgpool will authenticate based on the database's
+# name, not based on whether it exists or not.
+#
+# USER can be "all", a user name, or a comma-separated list thereof. In
+# both the DATABASE and USER fields you can also write a file name prefixed
+# with "@" to include names from a separate file. Note that a group name
+# prefixed with "+" like in PostgreSQL's pg_hba.conf file is not supported
+# because of the same reason as "samegroup" token. Also note that a user
+# name specified here may not exist in the backend PostgreSQL. pgpool will
+# authenticate based on the user's name, not based on whether he/she exists.
+#
+# CIDR-ADDRESS specifies the set of hosts the record matches.
+# It is made up of an IP address and a CIDR mask that is an integer
+# (between 0 and 32 (IPv4) that specifies the number of significant bits in
+# the mask. Alternatively, you can write an IP address and netmask in
+# separate columns to specify the set of hosts.
+#
+# METHOD can be "trust", "reject", or "pam". Note that "pam" sends passwords
+# in clear text.
+#
+# OPTION is the name of the PAM service. Default service name is "pgpool"
+#
+# Database and user names containing spaces, commas, quotes and other special
+# characters must be quoted. Quoting one of the keywords "all" or "sameuser"
+# makes the name lose its special character, and just match a database or
+# username with that name.
+#
+# This file is read on pgpool startup. If you edit the file on a running
+# system, you have to restart the pgpool for the changes to take effect.
+
+# Put your actual configuration here
+# ----------------------------------
+#
+# If you want to allow non-local connections, you need to add more
+# "host" records. In that case you will also need to make pgpool listen
+# on a non-local interface via the listen_addresses configuration parameter.
+#
+
+# TYPE DATABASE USER CIDR-ADDRESS METHOD
+
+# "local" is for Unix domain socket connections only
+local all all trust
+# IPv4 local connections:
+host all all 127.0.0.1/32 trust
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * This file was imported from PostgreSQL 8.0.8 source code.
+ * See below for the copyright and description.
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007 PgPool Global Development Group
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * 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.
+ *
+ * ------------------------------
+ *
+ *
+ * This file and the IPV6 implementation were initially provided by
+ * Nigel Kukard <nkukard@lbsd.net>, Linux Based Systems Design
+ * http://www.lbsd.net.
+ *
+ * pool_ip.c.: IPv6-aware network access.
+ *
+ */
+
+#include <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/un.h>
+#include "pool_ip.h"
+
+
+static int rangeSockAddrAF_INET(const struct sockaddr_in * addr,
+ const struct sockaddr_in * netaddr,
+ const struct sockaddr_in * netmask);
+
+#ifdef HAVE_IPV6
+static int rangeSockAddrAF_INET6(const struct sockaddr_in6 * addr,
+ const struct sockaddr_in6 * netaddr,
+ const struct sockaddr_in6 * netmask);
+#endif
+
+static int getaddrinfo_unix(const char *path,
+ const struct addrinfo * hintsp,
+ struct addrinfo ** result);
+
+static int getnameinfo_unix(const struct sockaddr_un * sa, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags);
+
+
+/*
+ * getaddrinfo_all - get address info for Unix, IPv4 and IPv6 sockets
+ */
+int
+getaddrinfo_all(const char *hostname, const char *servname,
+ const struct addrinfo * hintp, struct addrinfo ** result)
+{
+ /* not all versions of getaddrinfo() zero *result on failure */
+ *result = NULL;
+
+ if (hintp->ai_family == AF_UNIX)
+ return getaddrinfo_unix(servname, hintp, result);
+
+ /* NULL has special meaning to getaddrinfo(). */
+ return getaddrinfo((!hostname || hostname[0] == '\0') ? NULL : hostname,
+ servname, hintp, result);
+}
+
+
+/*
+ * freeaddrinfo_all - free addrinfo structures for IPv4, IPv6, or Unix
+ *
+ * Note: the ai_family field of the original hint structure must be passed
+ * so that we can tell whether the addrinfo struct was built by the system's
+ * getaddrinfo() routine or our own getaddrinfo_unix() routine. Some versions
+ * of getaddrinfo() might be willing to return AF_UNIX addresses, so it's
+ * not safe to look at ai_family in the addrinfo itself.
+ */
+void
+freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai)
+{
+ if (hint_ai_family == AF_UNIX)
+ {
+ /* struct was built by getaddrinfo_unix (see getaddrinfo_all) */
+ while (ai != NULL)
+ {
+ struct addrinfo *p = ai;
+
+ ai = ai->ai_next;
+ free(p->ai_addr);
+ free(p);
+ }
+ }
+ else
+ {
+ /* struct was built by getaddrinfo() */
+ if (ai != NULL)
+ freeaddrinfo(ai);
+ }
+}
+
+
+/*
+ * getnameinfo_all - get name info for Unix, IPv4 and IPv6 sockets
+ *
+ * The API of this routine differs from the standard getnameinfo() definition
+ * in two ways: first, the addr parameter is declared as sockaddr_storage
+ * rather than struct sockaddr, and second, the node and service fields are
+ * guaranteed to be filled with something even on failure return.
+ */
+int
+getnameinfo_all(const struct sockaddr_storage * addr, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags)
+{
+ int rc;
+
+ if (addr && addr->ss_family == AF_UNIX)
+ rc = getnameinfo_unix((const struct sockaddr_un *) addr, salen,
+ node, nodelen,
+ service, servicelen,
+ flags);
+ else
+ rc = getnameinfo((const struct sockaddr *) addr, salen,
+ node, nodelen,
+ service, servicelen,
+ flags);
+
+ if (rc != 0)
+ {
+ if (node)
+ strncpy(node, "???", nodelen);
+ if (service)
+ strncpy(service, "???", servicelen);
+ }
+
+ return rc;
+}
+
+
+const char *
+gai_strerror(int errcode)
+{
+ int hcode;
+
+ switch (errcode)
+ {
+ case EAI_NONAME:
+ hcode = HOST_NOT_FOUND;
+ break;
+ case EAI_AGAIN:
+ hcode = TRY_AGAIN;
+ break;
+ case EAI_FAIL:
+ default:
+ hcode = NO_RECOVERY;
+ break;
+ }
+
+ return hstrerror(hcode);
+}
+
+
+/*
+ * getaddrinfo_unix - get unix socket info using IPv6-compatible API
+ *
+ * Bugs: only one addrinfo is set even though hintsp is NULL or
+ * ai_socktype is 0
+ * AI_CANONNAME is not supported.
+ *
+ */
+static int
+getaddrinfo_unix(const char *path, const struct addrinfo * hintsp,
+ struct addrinfo ** result)
+{
+ struct addrinfo hints;
+ struct addrinfo *aip;
+ struct sockaddr_un *unp;
+
+ *result = NULL;
+
+ memset(&hints, 0, sizeof(hints));
+
+ if (strlen(path) >= sizeof(unp->sun_path))
+ return EAI_FAIL;
+
+ if (hintsp == NULL)
+ {
+ hints.ai_family = AF_UNIX;
+ hints.ai_socktype = SOCK_STREAM;
+ }
+ else
+ memcpy(&hints, hintsp, sizeof(hints));
+
+ if (hints.ai_socktype == 0)
+ hints.ai_socktype = SOCK_STREAM;
+
+ if (hints.ai_family != AF_UNIX)
+ {
+ /* shouldn't have been called */
+ return EAI_FAIL;
+ }
+
+ aip = calloc(1, sizeof(struct addrinfo));
+ if (aip == NULL)
+ return EAI_MEMORY;
+
+ unp = calloc(1, sizeof(struct sockaddr_un));
+ if (unp == NULL)
+ {
+ free(aip);
+ return EAI_MEMORY;
+ }
+
+ aip->ai_family = AF_UNIX;
+ aip->ai_socktype = hints.ai_socktype;
+ aip->ai_protocol = hints.ai_protocol;
+ aip->ai_next = NULL;
+ aip->ai_canonname = NULL;
+ *result = aip;
+
+ unp->sun_family = AF_UNIX;
+ aip->ai_addr = (struct sockaddr *) unp;
+ aip->ai_addrlen = sizeof(struct sockaddr_un);
+
+ strcpy(unp->sun_path, path);
+
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN
+ unp->sun_len = sizeof(struct sockaddr_un);
+#endif
+
+ return 0;
+}
+
+/*
+ * Convert an address to a hostname.
+ */
+static int
+getnameinfo_unix(const struct sockaddr_un * sa, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags)
+{
+ int ret = -1;
+
+ /* Invalid arguments. */
+ if (sa == NULL || sa->sun_family != AF_UNIX ||
+ (node == NULL && service == NULL))
+ return EAI_FAIL;
+
+ /* We don't support those. */
+ if ((node && !(flags & NI_NUMERICHOST))
+ || (service && !(flags & NI_NUMERICSERV)))
+ return EAI_FAIL;
+
+ if (node)
+ {
+ ret = snprintf(node, nodelen, "%s", "[local]");
+ if (ret == -1 || ret > nodelen)
+ return EAI_MEMORY;
+ }
+
+ if (service)
+ {
+ ret = snprintf(service, servicelen, "%s", sa->sun_path);
+ if (ret == -1 || ret > servicelen)
+ return EAI_MEMORY;
+ }
+
+ return 0;
+}
+
+
+/*
+ * rangeSockAddr - is addr within the subnet specified by netaddr/netmask ?
+ *
+ * Note: caller must already have verified that all three addresses are
+ * in the same address family; and AF_UNIX addresses are not supported.
+ */
+int
+rangeSockAddr(const struct sockaddr_storage * addr,
+ const struct sockaddr_storage * netaddr,
+ const struct sockaddr_storage * netmask)
+{
+ if (addr->ss_family == AF_INET)
+ return rangeSockAddrAF_INET((struct sockaddr_in *) addr,
+ (struct sockaddr_in *) netaddr,
+ (struct sockaddr_in *) netmask);
+#ifdef HAVE_IPV6
+ else if (addr->ss_family == AF_INET6)
+ return rangeSockAddrAF_INET6((struct sockaddr_in6 *) addr,
+ (struct sockaddr_in6 *) netaddr,
+ (struct sockaddr_in6 *) netmask);
+#endif
+ else
+ return 0;
+}
+
+static int
+rangeSockAddrAF_INET(const struct sockaddr_in * addr,
+ const struct sockaddr_in * netaddr,
+ const struct sockaddr_in * netmask)
+{
+ if (((addr->sin_addr.s_addr ^ netaddr->sin_addr.s_addr) &
+ netmask->sin_addr.s_addr) == 0)
+ return 1;
+ else
+ return 0;
+}
+
+
+#ifdef HAVE_IPV6
+static int
+rangeSockAddrAF_INET6(const struct sockaddr_in6 * addr,
+ const struct sockaddr_in6 * netaddr,
+ const struct sockaddr_in6 * netmask)
+{
+ int i;
+
+ for (i = 0; i < 16; i++)
+ {
+ if (((addr->sin6_addr.s6_addr[i] ^ netaddr->sin6_addr.s6_addr[i]) &
+ netmask->sin6_addr.s6_addr[i]) != 0)
+ return 0;
+ }
+
+ return 1;
+}
+#endif
+
+/*
+ * SockAddr_cidr_mask - make a network mask of the appropriate family
+ * and required number of significant bits
+ *
+ * The resulting mask is placed in *mask, which had better be big enough.
+ *
+ * Return value is 0 if okay, -1 if not.
+ */
+int
+SockAddr_cidr_mask(struct sockaddr_storage * mask, char *numbits, int family)
+{
+ long bits;
+ char *endptr;
+
+ bits = strtol(numbits, &endptr, 10);
+
+ if (*numbits == '\0' || *endptr != '\0')
+ return -1;
+
+ switch (family)
+ {
+ case AF_INET:
+ {
+ struct sockaddr_in mask4;
+ long maskl;
+
+ if (bits < 0 || bits > 32)
+ return -1;
+ /* avoid "x << 32", which is not portable */
+ if (bits > 0)
+ maskl = (0xffffffffUL << (32 - (int) bits))
+ & 0xffffffffUL;
+ else
+ maskl = 0;
+ mask4.sin_addr.s_addr = htonl(maskl);
+ memcpy(mask, &mask4, sizeof(mask4));
+ break;
+ }
+
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ {
+ struct sockaddr_in6 mask6;
+ int i;
+
+ if (bits < 0 || bits > 128)
+ return -1;
+ for (i = 0; i < 16; i++)
+ {
+ if (bits <= 0)
+ mask6.sin6_addr.s6_addr[i] = 0;
+ else if (bits >= 8)
+ mask6.sin6_addr.s6_addr[i] = 0xff;
+ else
+ {
+ mask6.sin6_addr.s6_addr[i] =
+ (0xff << (8 - (int) bits)) & 0xff;
+ }
+ bits -= 8;
+ }
+ memcpy(mask, &mask6, sizeof(mask6));
+ break;
+ }
+#endif
+ default:
+ return -1;
+ }
+
+ mask->ss_family = family;
+ return 0;
+}
+
+
+#ifdef HAVE_IPV6
+
+/*
+ * promote_v4_to_v6_addr --- convert an AF_INET addr to AF_INET6, using
+ * the standard convention for IPv4 addresses mapped into IPv6 world
+ *
+ * The passed addr is modified in place; be sure it is large enough to
+ * hold the result! Note that we only worry about setting the fields
+ * that rangeSockAddr will look at.
+ */
+void
+promote_v4_to_v6_addr(struct sockaddr_storage * addr)
+{
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ uint32 ip4addr;
+
+ memcpy(&addr4, addr, sizeof(addr4));
+ ip4addr = ntohl(addr4.sin_addr.s_addr);
+
+ memset(&addr6, 0, sizeof(addr6));
+
+ addr6.sin6_family = AF_INET6;
+
+ addr6.sin6_addr.s6_addr[10] = 0xff;
+ addr6.sin6_addr.s6_addr[11] = 0xff;
+ addr6.sin6_addr.s6_addr[12] = (ip4addr >> 24) & 0xFF;
+ addr6.sin6_addr.s6_addr[13] = (ip4addr >> 16) & 0xFF;
+ addr6.sin6_addr.s6_addr[14] = (ip4addr >> 8) & 0xFF;
+ addr6.sin6_addr.s6_addr[15] = (ip4addr) & 0xFF;
+
+ memcpy(addr, &addr6, sizeof(addr6));
+}
+
+/*
+ * promote_v4_to_v6_mask --- convert an AF_INET netmask to AF_INET6, using
+ * the standard convention for IPv4 addresses mapped into IPv6 world
+ *
+ * This must be different from promote_v4_to_v6_addr because we want to
+ * set the high-order bits to 1's not 0's.
+ *
+ * The passed addr is modified in place; be sure it is large enough to
+ * hold the result! Note that we only worry about setting the fields
+ * that rangeSockAddr will look at.
+ */
+void
+promote_v4_to_v6_mask(struct sockaddr_storage * addr)
+{
+ struct sockaddr_in addr4;
+ struct sockaddr_in6 addr6;
+ uint32 ip4addr;
+ int i;
+
+ memcpy(&addr4, addr, sizeof(addr4));
+ ip4addr = ntohl(addr4.sin_addr.s_addr);
+
+ memset(&addr6, 0, sizeof(addr6));
+
+ addr6.sin6_family = AF_INET6;
+
+ for (i = 0; i < 12; i++)
+ addr6.sin6_addr.s6_addr[i] = 0xff;
+
+ addr6.sin6_addr.s6_addr[12] = (ip4addr >> 24) & 0xFF;
+ addr6.sin6_addr.s6_addr[13] = (ip4addr >> 16) & 0xFF;
+ addr6.sin6_addr.s6_addr[14] = (ip4addr >> 8) & 0xFF;
+ addr6.sin6_addr.s6_addr[15] = (ip4addr) & 0xFF;
+
+ memcpy(addr, &addr6, sizeof(addr6));
+}
+
+#endif /* HAVE_IPV6 */
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * This file was imported from PostgreSQL 8.0.8 source code.
+ * See below for the copyright and description.
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007 PgPool Global Development Group
+ * Portions Copyright (c) 2003-2005, 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_ip.h.: Definitions for IPv6-aware network access.
+ *
+ */
+
+#ifndef POOL_IP_H
+#define POOL_IP_H
+
+#include "pool_type.h"
+
+extern int getaddrinfo_all(const char *hostname, const char *servname,
+ const struct addrinfo * hintp,
+ struct addrinfo ** result);
+extern void freeaddrinfo_all(int hint_ai_family, struct addrinfo * ai);
+
+extern int getnameinfo_all(const struct sockaddr_storage * addr, int salen,
+ char *node, int nodelen,
+ char *service, int servicelen,
+ int flags);
+
+extern int rangeSockAddr(const struct sockaddr_storage * addr,
+ const struct sockaddr_storage * netaddr,
+ const struct sockaddr_storage * netmask);
+
+extern int SockAddr_cidr_mask(struct sockaddr_storage * mask,
+ char *numbits, int family);
+
+/* imported from PostgreSQL getaddrinfo.c */
+extern const char * gai_strerror(int errcode);
+
+#ifdef HAVE_IPV6
+extern void promote_v4_to_v6_addr(struct sockaddr_storage * addr);
+extern void promote_v4_to_v6_mask(struct sockaddr_storage * addr);
+#endif
+
+#define IS_AF_INET(fam) ((fam) == AF_INET)
+#define IS_AF_UNIX(fam) ((fam) == AF_UNIX)
+
+#endif /* IP_H */
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007, PgPool Global Development Group
+ * 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_list.c.: Implementation of singly-linked homogeneous lists
+ *
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include "pool.h"
+#include "pool_type.h"
+#include "pool_list.h"
+
+static List * new_list(void);
+/* static void new_head_cell(List *list); */
+static void new_tail_cell(List *list);
+static void list_free_private(List *list, bool deep);
+
+#ifndef __GNUC__
+
+ListCell * list_head(List *l)
+{
+ return l ? l->head : NULL;
+}
+
+ListCell * list_tail(List *l)
+{
+ return l ? l->tail : NULL;
+}
+
+int list_length(List *l)
+{
+ return l ? l->length : 0;
+}
+
+#endif /* __GNUC__ */
+
+List * lappend(List *list, void *datum)
+{
+ if (list == NIL)
+ list = new_list();
+ else
+ new_tail_cell(list);
+
+ lfirst(list->tail) = datum;
+
+ return list;
+}
+
+List * lappend_int(List *list, int datum)
+{
+ if (list == NIL)
+ list = new_list();
+ else
+ new_tail_cell(list);
+
+ lfirst_int(list->tail) = datum;
+
+ return list;
+}
+
+static List * new_list(void)
+{
+ List *new_list;
+ ListCell *new_head;
+
+ new_head = (ListCell *)malloc(sizeof(*new_head));
+ if (new_head == NULL)
+ {
+ pool_error("new_list: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ new_head->next = NULL;
+
+ new_list = (List *)malloc(sizeof(*new_list));
+ if (new_list == NULL)
+ {
+ pool_error("new_list: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ new_list->length = 1;
+ new_list->head = new_head;
+ new_list->tail = new_head;
+
+ return new_list;
+}
+
+#ifdef NOT_USED
+static void new_head_cell(List *list)
+{
+ ListCell *new_head;
+
+ new_head = (ListCell *)malloc(sizeof(*new_head));
+ if (new_head == NULL)
+ {
+ pool_error("new_head_cell: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ new_head->next = list->head;
+
+ list->head = new_head;
+ list->length++;
+}
+#endif
+
+static void new_tail_cell(List *list)
+{
+ ListCell *new_tail;
+
+ new_tail = (ListCell *)malloc(sizeof(*new_tail));
+ if (new_tail == NULL)
+ {
+ pool_error("new_tail_cell: malloc failed: %s", strerror(errno));
+ exit(1);
+ }
+ new_tail->next = NULL;
+
+ list->tail->next = new_tail;
+ list->tail = new_tail;
+ list->length++;
+}
+
+/*
+ * free all storage in a list, but not the pointed-to elements
+ */
+void list_free(List *list)
+{
+ list_free_private(list, false);
+}
+
+/*
+ * free all storage in a list, and the pointed-to elements iff deep is true
+ */
+static void list_free_private(List *list, bool deep)
+{
+ ListCell *cell;
+
+ cell = list_head(list);
+ while (cell != NULL)
+ {
+ ListCell *tmp = cell;
+
+ cell = lnext(cell);
+ if (deep)
+ free(lfirst(tmp));
+ free(tmp);
+ }
+
+ if (list)
+ free(list);
+}
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007, PgPool Global Development Group
+ * 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_list.h.: interface to pool_list.c
+ *
+ */
+
+#ifndef POOL_LIST_H
+#define POOL_LIST_H
+
+#include <stdlib.h>
+
+#define NIL ((List *) NULL)
+
+#define lnext(lc) ((lc)->next)
+#define lfirst(lc) ((lc)->data.ptr_value)
+#define lfirst_int(lc) ((lc)->data.int_value)
+#define foreach(cell, l) \
+ for ((cell) = list_head(l); (cell) != NULL; (cell) = lnext(cell))
+#define forboth(cell1, list1, cell2, list2) \
+ for ((cell1) = list_head(list1), (cell2) = list_head(list2); \
+ (cell1) != NULL && (cell2) != NULL; \
+ (cell1) = lnext(cell1), (cell2) = lnext(cell2))
+
+typedef struct ListCell ListCell;
+
+typedef struct List
+{
+ int length;
+ ListCell *head;
+ ListCell *tail;
+} List;
+
+struct ListCell
+{
+ union
+ {
+ void *ptr_value;
+ int int_value;
+ } data;
+ ListCell *next;
+};
+
+#ifdef __GNUC__
+
+static __inline__ ListCell *
+list_head(List *l)
+{
+ return l ? l->head : NULL;
+}
+
+static __inline__ ListCell *
+list_tail(List *l)
+{
+ return l ? l->tail : NULL;
+}
+
+static __inline__ int
+list_length(List *l)
+{
+ return l ? l->length : 0;
+}
+
+#else
+
+extern ListCell * list_head(List *l);
+extern ListCell * list_tail(List *l);
+extern int list_length(List *l);
+
+#endif /* __GNUC__ */
+
+extern List * lappend(List *list, void *datum);
+extern List * lappend_int(List *list, int datum);
+extern void list_free(List *list);
+
+#endif /* POOL_LIST_H */
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007, PgPool Global Development Group
+ * 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_path.c.: small functions to manipulate paths
+ *
+ */
+
+#include "pool_type.h"
+#include "pool_path.h"
+#include <stdio.h>
+#include <string.h>
+
+static void trim_directory(char *path);
+static void trim_trailing_separator(char *path);
+
+/*
+ * get_parent_directory
+ *
+ * Modify the given string in-place to name the parent directory of the
+ * named file.
+ */
+void get_parent_directory(char *path)
+{
+ trim_directory(path);
+}
+
+
+/*
+ * trim_directory
+ *
+ * Trim trailing directory from path, that is, remove any trailing slashes,
+ * the last pathname component, and the slash just ahead of it --- but never
+ * remove a leading slash.
+ */
+static void trim_directory(char *path)
+{
+ char *p;
+
+ if (path[0] == '\0')
+ return;
+
+ /* back up over trailing slash(es) */
+ for (p = path + strlen(path) - 1; IS_DIR_SEP(*p) && p > path; p--);
+
+ /* back up over directory name */
+ for (; !IS_DIR_SEP(*p) && p > path; p--);
+
+ /* if multiple slashes before directory name, remove 'em all */
+ for (; p > path && IS_DIR_SEP(*(p - 1)); p--);
+
+ /* don't erase a leading slash */
+ if (p == path && IS_DIR_SEP(*p))
+ p++;
+
+ *p = '\0';
+}
+
+
+/*
+ * join_path_components - join two path components, inserting a slash
+ *
+ * ret_path is the output area (must be of size MAXPGPATH)
+ *
+ * ret_path can be the same as head, but not the same as tail.
+ */
+void join_path_components(char *ret_path, const char *head, const char *tail)
+{
+ if (ret_path != head)
+ StrNCpy(ret_path, head, MAXPGPATH);
+
+ /*
+ * Remove any leading "." and ".." in the tail component,
+ * adjusting head as needed.
+ */
+ for (;;)
+ {
+ if (tail[0] == '.' && IS_DIR_SEP(tail[1]))
+ {
+ tail += 2;
+ }
+ else if (tail[0] == '.' && tail[1] == '\0')
+ {
+ tail += 1;
+ break;
+ }
+ else if (tail[0] == '.' && tail[1] == '.' && IS_DIR_SEP(tail[2]))
+ {
+ trim_directory(ret_path);
+ tail += 3;
+ }
+ else if (tail[0] == '.' && tail[1] == '.' && tail[2] == '\0')
+ {
+ trim_directory(ret_path);
+ tail += 2;
+ break;
+ }
+ else
+ break;
+ }
+
+ if (*tail)
+ snprintf(ret_path + strlen(ret_path), MAXPGPATH - strlen(ret_path), "/%s", tail);
+}
+
+
+/*
+ * Clean up path by:
+ * o remove trailing slash
+ * o remove duplicate adjacent separators
+ * o remove trailing '.'
+ * o process trailing '..' ourselves
+ */
+void canonicalize_path(char *path)
+{
+ char *p, *to_p;
+ bool was_sep = false;
+
+ /*
+ * Removing the trailing slash on a path means we never get ugly
+ * double trailing slashes.
+ */
+ trim_trailing_separator(path);
+
+ /*
+ * Remove duplicate adjacent separators
+ */
+ p = path;
+ to_p = p;
+ for (; *p; p++, to_p++)
+ {
+ /* Handle many adjacent slashes, like "/a///b" */
+ while (*p == '/' && was_sep)
+ p++;
+ if (to_p != p)
+ *to_p = *p;
+ was_sep = (*p == '/');
+ }
+ *to_p = '\0';
+
+ /*
+ * Remove any trailing uses of "." and process ".." ourselves
+ */
+ for (;;)
+ {
+ int len = strlen(path);
+
+ if (len > 2 && strcmp(path + len - 2, "/.") == 0)
+ trim_directory(path);
+ else if (len > 3 && strcmp(path + len - 3, "/..") == 0)
+ {
+ trim_directory(path);
+ trim_directory(path);
+ /* remove directory above */
+ }
+ else
+ break;
+ }
+}
+
+
+/*
+ * trim_trailing_separator
+ *
+ * trim off trailing slashes, but not a leading slash
+ */
+static void trim_trailing_separator(char *path)
+{
+ char *p;
+
+ p = path + strlen(path);
+ if (p > path)
+ for (p--; p > path && IS_DIR_SEP(*p); p--)
+ *p = '\0';
+}
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007, PgPool Global Development Group
+ * 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_path.h.: interface to pool_path.c
+ *
+ */
+
+#ifndef POOL_PATH_H
+#define POOL_PATH_H
+
+/*
+ * MAXPGPATH: standard size of a pathname buffer in PostgreSQL (hence,
+ * maximum usable pathname length is one less).
+ *
+ * We'd use a standard system header symbol for this, if there weren't
+ * so many to choose from: MAXPATHLEN, MAX_PATH, PATH_MAX are all
+ * defined by different "standards", and often have different values
+ * on the same platform! So we just punt and use a reasonably
+ * generous setting here.
+ */
+#define MAXPGPATH 1024
+
+#define IS_DIR_SEP(ch) ((ch) == '/')
+#define is_absolute_path(filename) \
+( \
+ ((filename)[0] == '/') \
+)
+
+/*
+ * StrNCpy
+ * Like standard library function strncpy(), except that result string
+ * is guaranteed to be null-terminated --- that is, at most N-1 bytes
+ * of the source string will be kept.
+ * Also, the macro returns no result (too hard to do that without
+ * evaluating the arguments multiple times, which seems worse).
+ *
+ * BTW: when you need to copy a non-null-terminated string (like a text
+ * datum) and add a null, do not do it with StrNCpy(..., len+1). That
+ * might seem to work, but it fetches one byte more than there is in the
+ * text object. One fine day you'll have a SIGSEGV because there isn't
+ * another byte before the end of memory. Don't laugh, we've had real
+ * live bug reports from real live users over exactly this mistake.
+ * Do it honestly with "memcpy(dst,src,len); dst[len] = '\0';", instead.
+ */
+#define StrNCpy(dst,src,len) \
+ do \
+ { \
+ char * _dst = (dst); \
+ size_t _len = (len); \
+\
+ if (_len > 0) \
+ { \
+ strncpy(_dst, (src), _len); \
+ _dst[_len-1] = '\0'; \
+ } \
+ } while (0)
+
+extern void get_parent_directory(char *path);
+extern void join_path_components(char *ret_path, const char *head, const char *tail);
+extern void canonicalize_path(char *path);
+
+#endif /* POOL_PATH_H */
status[i].desc = "number of queries in reset_query_list";
i++;
+ status[i].name = "log_statement";
+ snprintf(status[i].value, MAXVALLEN, "%d", pool_config.log_statement);
+ status[i].desc = "if true, print all statements to the log";
+ i++;
+
+ status[i].name = "log_connections";
+ snprintf(status[i].value, MAXVALLEN, "%d", pool_config.log_connections);
+ status[i].desc = "if true, print incoming connections to the log";
+ i++;
+
+ status[i].name = "enable_pool_hba";
+ snprintf(status[i].value, MAXVALLEN, "%d", pool_config.enable_pool_hba);
+ status[i].desc = "if true, use pool_hba.conf for client authentication";
+ i++;
+
status[i].name = "server_status";
if (pool_config.server_status[0] == 0)
--- /dev/null
+/* -*-pgsql-c-*- */
+/*
+ *
+ * $Header$
+ *
+ * pgpool: a language independent connection pool server for PostgreSQL
+ * written by Tatsuo Ishii
+ *
+ * Portions Copyright (c) 2003-2007, PgPool Global Development Group
+ * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * 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_type.h.: definition of new types
+ *
+ */
+
+#ifndef POOL_TYPE_H
+#define POOL_TYPE_H
+
+
+#include "config.h"
+#include <sys/socket.h>
+
+
+/* Define common boolean type. C++ and BEOS already has it so exclude them. */
+#ifdef c_plusplus
+#ifndef __cplusplus
+#define __cplusplus
+#endif /* __cplusplus */
+#endif /* c_plusplus */
+
+#ifndef __BEOS__
+#ifndef __cplusplus
+#ifndef bool
+typedef char bool;
+#endif
+#ifndef true
+#define true ((bool) 1)
+#endif
+#ifndef false
+#define false ((bool) 0)
+#endif
+#endif /* not C++ */
+#endif /* __BEOS__ */
+
+
+/*
+ * It seems that sockaddr_storage is now commonly used in place of sockaddr.
+ * So, define it if it is not define yet, and create new SockAddr structure
+ * that uses sockaddr_storage.
+ */
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE
+
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY
+#define ss_family __ss_family
+#else
+#error struct sockaddr_storage does not provide an ss_family member
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_FAMILY */
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY */
+
+#ifdef HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN
+#define ss_len __ss_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE___SS_LEN */
+
+#else /* !HAVE_STRUCT_SOCKADDR_STORAGE */
+
+/* Define a struct sockaddr_storage if we don't have one. */
+struct sockaddr_storage
+{
+ union
+ {
+ struct sockaddr sa; /* get the system-dependent fields */
+ long int ss_align; /* ensures struct is properly aligned. original uses int64 */
+ char ss_pad[128]; /* ensures struct has desired size */
+ }
+ ss_stuff;
+};
+
+#define ss_family ss_stuff.sa.sa_family
+/* It should have an ss_len field if sockaddr has sa_len. */
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+#define ss_len ss_stuff.sa.sa_len
+#define HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN 1
+#endif
+#endif /* HAVE_STRUCT_SOCKADDR_STORAGE */
+
+typedef struct
+{
+ struct sockaddr_storage addr;
+ /* ACCEPT_TYPE_ARG3 - Third argument type of accept().
+ * It is defined in ac_func_accept_argtypes.m4
+ * If a need to run aclocal arises, be sure to use "-I ./" option.
+ */
+ ACCEPT_TYPE_ARG3 salen;
+}
+SockAddr;
+
+
+/* UserAuth type used for HBA which indicates the authentication method */
+typedef enum UserAuth
+{
+ uaReject,
+/* uaKrb4, */
+/* uaKrb5, */
+ uaTrust
+/* uaIdent, */
+/* uaPassword, */
+/* uaCrypt, */
+/* uaMD5, */
+#ifdef USE_PAM
+ ,uaPAM
+#endif /* USE_PAM */
+}
+UserAuth;
+
+#define AUTH_REQ_OK 0 /* User is authenticated */
+#define AUTH_REQ_KRB4 1 /* Kerberos V4 */
+#define AUTH_REQ_KRB5 2 /* Kerberos V5 */
+#define AUTH_REQ_PASSWORD 3 /* Password */
+#define AUTH_REQ_CRYPT 4 /* crypt password */
+#define AUTH_REQ_MD5 5 /* md5 password */
+#define AUTH_REQ_SCM_CREDS 6 /* transfer SCM credentials */
+
+typedef unsigned int AuthRequest;
+
+#endif /* POOL_TYPE_H */