Pound-2.8/ 0000775 0001750 0001750 00000000000 13275266545 011511 5 ustar roseg roseg Pound-2.8/Makefile.in 0000644 0001750 0001750 00000004615 13275266545 013562 0 ustar roseg roseg # Pound - the reverse-proxy load-balancer
# Copyright (C) 2002-2010 Apsis GmbH
#
# This file is part of Pound.
#
# Pound is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Pound is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Contact information:
# Apsis GmbH
# P.O.Box
# 8707 Uetikon am See
# Switzerland
# EMail: roseg@apsis.ch
CC=@PTHREAD_CC@
CFLAGS=-DF_CONF=\"@sysconfdir@/pound.cfg\" -DVERSION=\"@PACKAGE_VERSION@\" -DC_SSL=\"@C_SSL@\" -DC_T_RSA=\"@C_T_RSA@\" \
-DC_DH_LEN=\"@C_DH_LEN@\" -DC_MAXBUF=\"@C_MAXBUF@\" -DC_OWNER=\"@C_OWNER@\" -DC_GROUP=\"@C_GROUP@\" \
-DC_SUPER=\"@C_SUPER@\" @CFLAGS@ @PTHREAD_CFLAGS@ @CPPFLAGS@
LIBS=@LIBS@ @PTHREAD_LIBS@
prefix=@prefix@
exec_prefix=@exec_prefix@
# Configuration file default; if none, look at config.c for default!
OBJS=pound.o http.o config.o svc.o
all: pound poundctl pound.8
pound: $(OBJS)
${CC} @LDFLAGS@ -o pound $(OBJS) $(LIBS)
poundctl: poundctl.o
${CC} @LDFLAGS@ -o poundctl poundctl.o $(LIBS)
dh512.h:
openssl dhparam -5 -C -noout 512 > dh512.h
dh@C_DH_LEN@.h:
openssl dhparam -5 -C -noout @C_DH_LEN@ > dh@C_DH_LEN@.h
svc.o: svc.c dh512.h dh@C_DH_LEN@.h
${CC} ${CFLAGS} -c -o svc.o svc.c
$(OBJS) poundctl.o: pound.h config.h
install: all
@INSTALL@ -d ${DESTDIR}@sbindir@
@INSTALL@ -o @I_OWNER@ -g @I_GRP@ -m 555 pound ${DESTDIR}@sbindir@/pound
@INSTALL@ -o @I_OWNER@ -g @I_GRP@ -m 555 poundctl ${DESTDIR}@sbindir@/poundctl
@INSTALL@ -d ${DESTDIR}@mandir@/man8
@INSTALL@ -o @I_OWNER@ -g @I_GRP@ -m 644 pound.8 ${DESTDIR}@mandir@/man8/pound.8
@INSTALL@ -o @I_OWNER@ -g @I_GRP@ -m 644 poundctl.8 ${DESTDIR}@mandir@/man8/poundctl.8
clean:
rm -f pound $(OBJS) poundctl poundctl.o
rm -f dh512.h dh@C_DH_LEN@.h
distclean: clean
-rm -f config.h config.log config.status Makefile
uninstall:
-rm -f @sbindir@/pound @sbindir@/poundctl @mandir@/man8/pound.8 @mandir@/cat8/pound.8 @mandir@/man8/poundctl.8 @mandir@/cat8/poundctl.8
Pound-2.8/z2_2_5_1.py 0000755 0001750 0001750 00000060101 13275266545 013302 0 ustar roseg roseg ##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Zope 2 ZServer start-up file
Usage: %(program)s [options] [environment settings]
Options:
-h
Output this text.
-z path
The location of the Zope installation.
The default is the location of this script, %(here)s.
-Z path
Unix only! This option is ignored on windows.
If this option is specified, a separate managemnt process will
be created that restarts Zope after a shutdown (or crash).
The path must point to a pid file that the process will record its
process id in. The path may be relative, in which case it will be
relative to the Zope location.
To prevent use of a separate management process, provide an
empty string: -Z ''
-t n
The number of threads to use, if ZODB3 is used. The default is
%(NUMBER_OF_THREADS)s.
-i n
Set the interpreter check interval. This integer value
determines how often the interpreter checks for periodic things
such as thread switches and signal handlers. The Zope default
is 120, but you may want to experiment with other values that
may increase performance in your particular environment.
-D
Run in Zope debug mode. This causes the Zope process not to
detach from the controlling terminal, and is equivalent to
supplying the environment variable setting Z_DEBUG_MODE=1
-a ipaddress
The IP address to listen on. If this is an empty string
(e.g. -a ''), then all addresses on the machine are used. The
default is %(IP_ADDRESS)s.
-d ipaddress
IP address of your DNS server. If this is an empty string
(e.g. -d ''), then IP addresses will not be logged. If you have
DNS service on your local machine then you can set this to
127.0.0.1. The default is: %(DNS_IP)s.
-u username or uid number
The username to run ZServer as. You may want to run ZServer as 'nobody'
or some other user with limited resouces. The only works under Unix, and
if ZServer is started by root. The default is: %(UID)s
-P [ipaddress:]number
Set the web, ftp and monitor port numbers simultaneously
as offsets from the number. The web port number will be number+80.
The FTP port number will be number+21. The monitor port number will
be number+99.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -P options can be provided to run multiple sets of servers.
-w port
The Web server (HTTP) port. This defaults to %(HTTP_PORT)s. The
standard port for HTTP services is 80. If this is a dash
(e.g. -w -), then HTTP is disabled.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -w options can be provided to run multiple servers.
-y port
The encrypted Web server (HTTPS) port. This defaults to %(HTTPS_PORT)s.
The standard port for HTTP services is 443. If this is a dash
(e.g. -y -), then HTTPS is disabled.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -y options can be provided to run multiple servers.
-W port
The "WebDAV source" port. If this is a dash (e.g. -W -), then
"WebDAV source" is disabled. The default is disabled. Note that
this feature is a workaround for the lack of "source-link" support
in standard WebDAV clients.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -W options can be provided to run multiple servers.
-f port
The FTP port. If this is a dash (e.g. -f -), then FTP
is disabled. The standard port for FTP services is 21. The
default is %(FTP_PORT)s.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -f options can be provided to run multiple servers.
-p path
Path to the PCGI resource file. The default value is
%(PCGI_FILE)s, relative to the Zope location. If this is a dash
(-p -) or the file does not exist, then PCGI is disabled.
-F path_or_port
Either a port number (for inet sockets) or a path name (for unix
domain sockets) for the FastCGI Server. If the flag and value are
not specified then the FastCGI Server is disabled.
-m port
The secure monitor server port. If this is a dash
(-m -), then the monitor server is disabled. The monitor server
allows interactive Python style access to a running ZServer. To
access the server see medusa/monitor_client.py or
medusa/monitor_client_win32.py. The monitor server password is the
same as the Zope emergency user password set in the 'access'
file. The default is to not start up a monitor server.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -m options can be provided to run multiple servers.
-l path
Path to the ZServer log file. If this is a relative path then the
log file will be written to the 'var' directory. The default is
%(LOG_FILE)s.
-r
Run ZServer is read-only mode. ZServer won't write anything to disk.
No log files, no pid files, nothing. This means that you can't do a
lot of stuff like use PCGI, and zdaemon. ZServer will log hits to
STDOUT and zLOG will log to STDERR.
-L
Enable locale (internationalization) support. The value passed for
this option should be the name of the locale to be used (see your
operating system documentation for locale information specific to
your system). If an empty string is passed for this option (-L ''),
Zope will set the locale to the user's default setting (typically
specified in the $LANG environment variable). If your Python
installation does not support the locale module, the requested
locale is not supported by your system or an empty string was
passed but no default locale can be found, an error will be raised
and Zope will not start.
-X
Disable servers. This might be used to effectively disable all
default server settings or previous server settings in the option
list before providing new settings. For example to provide just a
web server:
%(program)s -X -w80
-M file
Save detailed logging information to the given file.
This log includes separate entries for:
- The start of a request,
- The start of processing the request in an application thread,
- The start of response output, and
- The end of the request.
Environment settings are of the form: NAME=VALUE.
Note: you *must* use Python 2.1 or later!
"""
# This is required path hackery for the win32 binary distribution
# that ensures that the bundled python libraries are used. In a
# win32 binary distribution, the installer will have replaced the
# marker string with the actual software home. If that has not
# happened, then the path munging code is skipped.
swhome=r'INSERT_SOFTWARE_HOME'
if swhome != 'INSERT_SOFTWARE_HOME':
import sys
sys.path.insert(0, '%s/lib/python' % swhome)
sys.path.insert(1, '%s/bin/lib' % swhome)
sys.path.insert(2, '%s/bin/lib/plat-win' % swhome)
sys.path.insert(3, '%s/bin/lib/win32' % swhome)
sys.path.insert(4, '%s/bin/lib/win32/lib' % swhome)
sys.path.insert(5, '%s' % swhome)
import os, sys, getopt, string, codecs
# workaround to allow unicode encoding conversions in DTML
dummy = codecs.lookup('iso-8859-1')
sys.setcheckinterval(120)
program=sys.argv[0]
here=os.path.join(os.getcwd(), os.path.split(program)[0])
Zpid=''
########################################################################
# Configuration section
## General configuration options
##
# If you want run as a daemon, then uncomment the line below:
if sys.platform=='win32': Zpid=''
else: Zpid='zProcessManager.pid'
# This is the IP address of the network interface you want your servers to
# be visible from. This can be changed to '' to listen on all interfaces.
IP_ADDRESS=''
# IP address of your DNS server. Set to '' if you do not want to resolve
# IP addresses. If you have DNS service on your local machine then you can
# set this to '127.0.0.1'
DNS_IP=''
# User id to run ZServer as. Note that this only works under Unix, and if
# ZServer is started by root.
UID='nobody'
# Log file location. If this is a relative path, then it is joined the
# the 'var' directory.
LOG_FILE='Z2.log'
## HTTP configuration
##
# Port for HTTP Server. The standard port for HTTP services is 80.
HTTP_PORT=8080
# HTTP enivornment settings.
HTTP_ENV={}
# Port for HTTPS Server. The standard port for HTTPS services is 443.
HTTPS_PORT=8443
# HTTPS enivornment settings.
HTTPS_ENV={}
# Port for the special "WebDAV source view" HTTP handler. There is no
# standard port for this handler, which is disabled by default.
WEBDAV_SOURCE_PORT=[]
## FTP configuration
# Port for the FTP Server. The standard port for FTP services is 21.
FTP_PORT=8021
## PCGI configuration
# You can configure the PCGI server manually, or have it read its
# configuration information from a PCGI info file.
PCGI_FILE='Zope.cgi'
## Monitor configuration
MONITOR_PORT=0
# Module to be published, which must be Main or Zope
MODULE='Zope'
# The size of the thread pool, if ZODB3 is used.
NUMBER_OF_THREADS=4
# Localization support
LOCALE_ID=None
# Socket path or port for the FastCGI Server
FCGI_PORT=None
# Detailed log file
DETAILED_LOG_FILE=''
#
########################################################################
########################################################################
# Handle command-line arguments:
def server_info(old, v, offset=0):
# interpret v as a port or address/port and get new value
if v == '-': v=''
l=string.find(v, ':')
if l >= 0:
a=v[:l]
v=v[l+1:]
else:
a=IP_ADDRESS
if not v: return v
try:
v=string.atoi(v)
if v < 0: raise 'Invalid port', v
v=v+offset
except: raise 'Invalid port', v
if type(old) is type(0): old=[(a,v)]
else: old.append((a,v))
return old
try:
if string.split(sys.version)[0] < '2.1':
raise 'Invalid python version', string.split(sys.version)[0]
opts, args = getopt.getopt(sys.argv[1:],
'hz:Z:t:i:a:d:u:w:y:W:f:p:m:Sl:2DP:rF:L:XM:')
DEBUG=0
READ_ONLY=0
# Get environment variables
for a in args:
if string.find(a,'='):
a=string.split(a,'=')
o=a[0]
v=string.join(a[1:],'=')
if o:
os.environ[o]=v
HTTP_ENV[o]=v
HTTPS_ENV[o]=v
else:
raise 'Invalid argument', a
for o, v in opts:
if o=='-z': here=v
elif o=='-Z':
if v=='-': v=''
Zpid=v
elif o=='-r': READ_ONLY=1
elif o=='-t':
try: v=string.atoi(v)
except: raise 'Invalid number of threads', v
NUMBER_OF_THREADS=v
elif o=='-i':
try: v=string.atoi(v)
except: raise 'Invalid value for -i option', v
sys.setcheckinterval(v)
elif o=='-a': IP_ADDRESS=v
elif o=='-d':
if v=='-': v=''
DNS_IP=v
elif o=='-u': UID=v
elif o=='-D':
os.environ['Z_DEBUG_MODE']='1'
DEBUG=1
elif o=='-S': sys.ZMANAGED=1
elif o=='-X':
MONITOR_PORT=HTTP_PORT=HTTPS_PORT=FTP_PORT=FCGI_PORT=0
PCGI_FILE=''
elif o=='-m':
MONITOR_PORT=server_info(MONITOR_PORT, v)
elif o=='-w':
HTTP_PORT=server_info(HTTP_PORT, v)
elif o=='-y':
HTTPS_PORT=server_info(HTTPS_PORT, v)
elif o=='-W':
WEBDAV_SOURCE_PORT=server_info(WEBDAV_SOURCE_PORT, v)
elif o=='-f':
FTP_PORT=server_info(FTP_PORT, v)
elif o=='-P':
HTTP_PORT=server_info(HTTP_PORT, v, 80)
HTTPS_PORT=server_info(HTTPS_PORT, v, 443)
FTP_PORT=server_info(FTP_PORT, v, 21)
elif o=='-p':
if v=='-': v=''
PCGI_FILE=v
elif o=='-h':
print __doc__ % vars()
sys.exit(0)
elif o=='-2': MODULE='Main'
elif o=='-l': LOG_FILE=v
elif o=='-L':
if v: LOCALE_ID=v
else: LOCALE_ID=''
elif o=='-F':
if v=='-': v=''
FCGI_PORT=v
elif o=='-M': DETAILED_LOG_FILE=v
except SystemExit: sys.exit(0)
except:
print __doc__ % vars()
print
print 'Error:'
print "%s: %s" % (sys.exc_type, sys.exc_value)
sys.exit(1)
if sys.platform=='win32': Zpid=''
#
########################################################################
########################################################################
# OK, let's get going!
# Jigger path:
sys.path=[os.path.join(here,'lib','python'),here
]+filter(None, sys.path)
# Try to set the locale if specified on the command
# line. If the locale module is not available or the
# requested locale is not supported by the local
# machine, raise an error so that the user is made
# aware of the problem.
def set_locale(val):
try:
import locale
except:
raise SystemExit, (
'The locale module could not be imported.\n'
'To use localization options, you must ensure\n'
'that the locale module is compiled into your\n'
'Python installation.'
)
try:
locale.setlocale(locale.LC_ALL, val)
except:
raise SystemExit, (
'The specified locale is not supported by your system.\n'
'See your operating system documentation for more\n'
'information on locale support.'
)
if LOCALE_ID is not None:
set_locale(LOCALE_ID)
# from this point forward we can use the zope logger
# Import ZServer before we open the database or get at interesting
# application code so that ZServer's asyncore gets to be the
# official one. Also gets SOFTWARE_HOME, INSTANCE_HOME, and CLIENT_HOME
import ZServer
if Zpid and not READ_ONLY:
import zdaemon, App.FindHomes, posix
sys.ZMANAGED=1
zdaemon.run(sys.argv, os.path.join(CLIENT_HOME, Zpid))
try:
# Import logging support
import zLOG
import ZLogger
if READ_ONLY:
if hasattr(zLOG, '_set_stupid_dest'):
zLOG._set_stupid_dest(sys.stderr)
else:
zLOG._stupid_dest = sys.stderr
else:
zLOG.log_write = ZLogger.ZLogger.log_write
if DETAILED_LOG_FILE:
from ZServer import DebugLogger
logfile=os.path.join(CLIENT_HOME, DETAILED_LOG_FILE)
DebugLogger.log=DebugLogger.DebugLogger(logfile).log
# Import Zope (or Main)
exec "import "+MODULE in {}
# Location of the ZServer log file. This file logs all ZServer activity.
# You may wish to create different logs for different servers. See
# medusa/logger.py for more information.
if not os.path.isabs(LOG_FILE):
LOG_PATH=os.path.join(CLIENT_HOME, LOG_FILE)
else:
LOG_PATH=LOG_FILE
# Location of the ZServer pid file. When ZServer starts up it will write
# its PID to this file.
PID_FILE=os.path.join(CLIENT_HOME, 'Z2.pid')
# import ZServer stuff
# First, we need to increase the number of threads
if MODULE=='Zope':
from ZServer import setNumberOfThreads
setNumberOfThreads(NUMBER_OF_THREADS)
from ZServer import resolver, logger, asyncore
from ZServer import zhttp_server, zhttp_handler
from ZServer.WebDAVSrcHandler import WebDAVSrcHandler
from ZServer import PCGIServer,FTPServer,FCGIServer
from ZServer import secure_monitor_server
## ZServer startup
##
# Resolver and Logger, used by other servers
if DNS_IP:
rs = resolver.caching_resolver(DNS_IP)
else:
rs=None
if READ_ONLY:
lg = logger.file_logger('-') # log to stdout
elif os.environ.has_key('ZSYSLOG'):
lg = logger.syslog_logger(os.environ['ZSYSLOG'])
if os.environ.has_key("ZSYSLOG_FACILITY"):
lg = logger.syslog_logger(os.environ['ZSYSLOG'],facility=os.environ['ZSYSLOG_FACILITY'])
else:
lg = logger.syslog_logger(os.environ['ZSYSLOG'])
elif os.environ.has_key('ZSYSLOG_SERVER'):
(addr, port) = string.split(os.environ['ZSYSLOG_SERVER'], ':')
lg = logger.syslog_logger((addr, int(port)))
else:
lg = logger.file_logger(LOG_PATH)
# HTTP Server
if HTTP_PORT:
if type(HTTP_PORT) is type(0): HTTP_PORT=((IP_ADDRESS, HTTP_PORT),)
for address, port in HTTP_PORT:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
zh = zhttp_handler(MODULE, '', HTTP_ENV)
hs.install_handler(zh)
# HTTPS Server
if HTTPS_PORT:
if type(HTTPS_PORT) is type(0): HTTPS_PORT=((IP_ADDRESS, HTTPS_PORT),)
for address, port in HTTPS_PORT:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
try:
del HTTPS_ENV['HTTP']
except KeyError:
pass
HTTPS_ENV['HTTPS']='ON'
zh = zhttp_handler(MODULE, '', HTTPS_ENV)
hs.install_handler(zh)
# WebDAV source Server (runs HTTP, but munges request to return
# 'manage_FTPget').
if WEBDAV_SOURCE_PORT:
if type(WEBDAV_SOURCE_PORT) is type(0):
WEBDAV_SOURCE_PORT=((IP_ADDRESS, WEBDAV_SOURCE_PORT),)
for address, port in WEBDAV_SOURCE_PORT:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
zh = WebDAVSrcHandler(MODULE, '', HTTP_ENV)
hs.install_handler(zh)
# FTP Server
if FTP_PORT:
if type(FTP_PORT) is type(0): FTP_PORT=((IP_ADDRESS, FTP_PORT),)
for address, port in FTP_PORT:
FTPServer(
module=MODULE,
ip=address,
port=port,
resolver=rs,
logger_object=lg)
# PCGI Server
if PCGI_FILE and not READ_ONLY:
PCGI_FILE=os.path.join(here, PCGI_FILE)
if os.path.exists(PCGI_FILE):
zpcgi = PCGIServer(
module=MODULE,
ip=IP_ADDRESS,
pcgi_file=PCGI_FILE,
resolver=rs,
logger_object=lg)
# FastCGI Server
if FCGI_PORT and not READ_ONLY:
fcgiPort = None
fcgiPath = None
try:
fcgiPort = string.atoi(FCGI_PORT)
except ValueError:
fcgiPath = FCGI_PORT
zfcgi = FCGIServer(module=MODULE,
ip=IP_ADDRESS,
port=fcgiPort,
socket_file=fcgiPath,
resolver=rs,
logger_object=lg)
# Monitor Server
if MONITOR_PORT:
from AccessControl.User import emergency_user
if not hasattr(emergency_user, '__null_user__'):
pw = emergency_user._getPassword()
else:
pw = None
zLOG.LOG("z2", zLOG.WARNING, 'Monitor server not started'
' because no emergency user exists.')
if pw:
if type(MONITOR_PORT) is type(0):
MONITOR_PORT=((IP_ADDRESS, MONITOR_PORT),)
for address, port in MONITOR_PORT:
monitor=secure_monitor_server(
password=pw,
hostname=address,
port=port)
# Try to set uid to "-u" -provided uid.
# Try to set gid to "-u" user's primary group.
# This will only work if this script is run by root.
try:
import pwd
try:
try: UID = string.atoi(UID)
except: pass
gid = None
if type(UID) == type(""):
uid = pwd.getpwnam(UID)[2]
gid = pwd.getpwnam(UID)[3]
elif type(UID) == type(1):
uid = pwd.getpwuid(UID)[2]
gid = pwd.getpwuid(UID)[3]
else:
raise KeyError
try:
if gid is not None:
try:
os.setgid(gid)
except OSError:
pass
os.setuid(uid)
except OSError:
pass
except KeyError:
zLOG.LOG("z2", zLOG.ERROR, ("can't find UID %s" % UID))
except:
pass
# if it hasn't failed at this point, create a .pid file.
if not READ_ONLY:
pf = open(PID_FILE, 'w')
pid=str(os.getpid())
try: pid=str(os.getppid())+' '+pid
except: pass
pf.write(pid)
pf.close()
except:
# Log startup exception and tell zdaemon not to restart us.
try:
zLOG.LOG("z2", zLOG.PANIC, "Startup exception",
error=sys.exc_info())
except: pass
sys.exit(0)
# Start Medusa, Ye Hass!
sys.ZServerExitCode=0
asyncore.loop()
sys.exit(sys.ZServerExitCode)
Pound-2.8/poundctl.8 0000755 0001750 0001750 00000003717 13275266545 013443 0 ustar roseg roseg .TH POUNDCTL "8" "Jan 2010" "poundctl" "System Manager's Manual"
.SH NAME
poundctl \- control the pound(8) daemon
.SH SYNOPSIS
.TP
.B poundctl \fI-c /path/to/socket\fR [\fI-L/-l\fR] [\fI-S/-s\fR] [\fI-B/-b\fR] [\fI-N/-n\fR] [\fI-H\fR] [\fI-X\fR]
.SH DESCRIPTION
.PP
.B Poundctl
controls various aspects of the operation of the
.I pound(8)
program.
.SH OPTIONS
Options available:
.TP
\fB\-c /path/to/socket\fR
The path to the (Unix-domain) socket
.B Pound
was configured to listen on for control. Your
.B Pound
configuration file must contain the directive
.I Control "/path/to/socket"
for
.B poundctl
to work.
.TP
\fB\-L/-l n\fR
Enable/disable a listener. A disabled listener will stop accepting connection
requests.
.TP
\fB\-S/-s n m\fR
Enable/disable a service. A disabled service will not be used by
.B Pound
to answer requests.
.TP
\fB\-B/-b n m r\fR
Enable/disable a back-end. A disabled back-end will not be passed requests to
answer. Note however that existing sessions may still cause requests to be
sent their way.
.TP
\fB\-N n m k r\fR
Add a session to service m in listener n. The session key is k and it points to
back-end r.
.TP
\fB\-n n m k\fR
Remove a session from service m in listener n. The session key is k.
.PP
The parameters n, m and r refer to the number assigned to a particular listener,
service and back-end in the listings. A listener number of -1 refers by convention
to the global context.
.TP
\fB\-H\fR
Try to resolve the addresses to symbolic names. Depending on your configuration,
this may require an active DNS.
.TP
\fB\-X\fR
Show the results in XML format.
.PP
When called without flags
.B poundctl
will print out a listing of the
.B Pound
internal state.
.SH AUTHOR
Written by Robert Segall, Apsis GmbH.
.SH "REPORTING BUGS"
Report bugs to .
.SH COPYRIGHT
Copyright \(co 2002-2010 Apsis GmbH.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Pound-2.8/config.guess 0000755 0001750 0001750 00000120665 13275266545 014041 0 ustar roseg roseg #! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-05-09'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner .
# Please send patches to . Submit a context
# diff and a properly formatted ChangeLog entry.
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
#
# The plan is that this can be called by configure scripts if you
# don't specify an explicit build system type.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION]
Output the configuration name of the system \`$me' is run on.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help" >&2
exit 1 ;;
* )
break ;;
esac
done
if test $# != 0; then
echo "$me: too many arguments$help" >&2
exit 1
fi
trap 'exit 1' 1 2 15
# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
# compiler to aid in system detection is discouraged as it requires
# temporary files to be created and, as you can see below, it is a
# headache to deal with in a portable fashion.
# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
# use `HOST_CC' if defined, but it is deprecated.
# Portable tmp directory creation inspired by the Autoconf team.
set_cc_for_build='
trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
: ${TMPDIR=/tmp} ;
{ tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
dummy=$tmp/dummy ;
tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
case $CC_FOR_BUILD,$HOST_CC,$CC in
,,) echo "int x;" > $dummy.c ;
for c in cc gcc c89 c99 ; do
if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
CC_FOR_BUILD="$c"; break ;
fi ;
done ;
if test x"$CC_FOR_BUILD" = x ; then
CC_FOR_BUILD=no_compiler_found ;
fi
;;
,,*) CC_FOR_BUILD=$CC ;;
,*,*) CC_FOR_BUILD=$HOST_CC ;;
esac ;'
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
# (ghazi@noc.rutgers.edu 1994-08-24)
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
PATH=$PATH:/.attbin ; export PATH
fi
UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
# compatibility and a consistent mechanism for selecting the
# object file format.
#
# Note: NetBSD doesn't particularly care about the vendor
# portion of the name. We always set it to "unknown".
sysctl="sysctl -n hw.machine_arch"
UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
/usr/sbin/$sysctl 2>/dev/null || echo unknown)`
case "${UNAME_MACHINE_ARCH}" in
armeb) machine=armeb-unknown ;;
arm*) machine=arm-unknown ;;
sh3el) machine=shl-unknown ;;
sh3eb) machine=sh-unknown ;;
*) machine=${UNAME_MACHINE_ARCH}-unknown ;;
esac
# The Operating System including object format, if it has switched
# to ELF recently, or will in the future.
case "${UNAME_MACHINE_ARCH}" in
arm*|i386|m68k|ns32k|sh3*|sparc|vax)
eval $set_cc_for_build
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep __ELF__ >/dev/null
then
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
# Return netbsd for either. FIX?
os=netbsd
else
os=netbsdelf
fi
;;
*)
os=netbsd
;;
esac
# The OS release
# Debian GNU/NetBSD machines have a different userland, and
# thus, need a distinct triplet. However, they do not need
# kernel version information, so it can be replaced with a
# suitable tag, in the style of linux-gnu.
case "${UNAME_VERSION}" in
Debian*)
release='-gnu'
;;
*)
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
;;
esac
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
# contains redundant information, the shorter form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
macppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvmeppc:OpenBSD:*:*)
echo powerpc-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mipseb-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:OpenBSD:*:*)
echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# According to Compaq, /usr/sbin/psrinfo has been available on
# OSF/1 and Tru64 systems produced since 1995. I hope that
# covers most systems running today. This code pipes the CPU
# types through head -n 1, so we only detect the type of CPU 0.
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
UNAME_MACHINE="alpha" ;;
"EV4.5 (21064)")
UNAME_MACHINE="alpha" ;;
"LCA4 (21066/21068)")
UNAME_MACHINE="alpha" ;;
"EV5 (21164)")
UNAME_MACHINE="alphaev5" ;;
"EV5.6 (21164A)")
UNAME_MACHINE="alphaev56" ;;
"EV5.6 (21164PC)")
UNAME_MACHINE="alphapca56" ;;
"EV5.7 (21164PC)")
UNAME_MACHINE="alphapca57" ;;
"EV6 (21264)")
UNAME_MACHINE="alphaev6" ;;
"EV6.7 (21264A)")
UNAME_MACHINE="alphaev67" ;;
"EV6.8CB (21264C)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8AL (21264B)")
UNAME_MACHINE="alphaev68" ;;
"EV6.8CX (21264D)")
UNAME_MACHINE="alphaev68" ;;
"EV6.9A (21264/EV69A)")
UNAME_MACHINE="alphaev69" ;;
"EV7 (21364)")
UNAME_MACHINE="alphaev7" ;;
"EV7.9 (21364A)")
UNAME_MACHINE="alphaev79" ;;
esac
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit 0 ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
# of the specific Alpha model?
echo alpha-pc-interix
exit 0 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
exit 0 ;;
Amiga*:UNIX_System_V:4.0:*)
echo m68k-unknown-sysv4
exit 0;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
*:[Mm]orph[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-morphos
exit 0 ;;
*:OS/390:*:*)
echo i370-ibm-openedition
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
exit 0 ;;
NILE*:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
DRS?6000:UNIX_SV:4.2*:7*)
case `/usr/bin/uname -p` in
sparc) echo sparc-icl-nx7 && exit 0 ;;
esac ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
# it's likely to be more like Solaris than SunOS4.
echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:*:*)
case "`/usr/bin/arch -k`" in
Series*|S4*)
UNAME_RELEASE=`uname -v`
;;
esac
# Japanese Language versions have a version number like `4.1.3-JL'.
echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
exit 0 ;;
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
# The situation for MiNT is a little confusing. The machine name
# can be virtually everything (everything which is not
# "atarist" or "atariste" at least should have a processor
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
# to the lowercase version "mint" (or "freemint"). Finally
# the system name "TOS" denotes a system which is actually not
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit 0 ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit 0 ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit 0 ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
2020:CLIX:*:* | 2430:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;;
mips:*:*:UMIPS | mips:*:*:RISCos)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __cplusplus
#include /* for printf() prototype */
int main (int argc, char *argv[]) {
#else
int main (argc, argv) int argc; char *argv[]; {
#endif
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c \
&& $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& exit 0
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
Motorola:PowerMAX_OS:*:*)
echo powerpc-motorola-powermax
exit 0 ;;
Motorola:*:4.3:PL8-*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
echo powerpc-harris-powermax
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
echo powerpc-harris-powerunix
exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
m88k:*:4*:R4*)
echo m88k-motorola-sysv4
exit 0 ;;
m88k:*:3*:R3*)
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
[ ${TARGET_BINARY_INTERFACE}x = x ]
then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit 0 ;;
M88*:*:R3*:*)
# Delta 88k system running SVR3
echo m88k-motorola-sysv3
exit 0 ;;
XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
echo m88k-tektronix-sysv3
exit 0 ;;
Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
echo m68k-tektronix-bsd
exit 0 ;;
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i*86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
ia64:AIX:*:*)
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:2:3)
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
main()
{
if (!__power_pc())
exit(1);
puts("powerpc-ibm-aix3.2.5");
exit(0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo rs6000-ibm-aix3.2.5
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
echo rs6000-ibm-aix3.2.4
else
echo rs6000-ibm-aix3.2
fi
exit 0 ;;
*:AIX:*:[45])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
else
IBM_ARCH=powerpc
fi
if [ -x /usr/bin/oslevel ] ; then
IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
fi
echo ${IBM_ARCH}-ibm-aix${IBM_REV}
exit 0 ;;
*:AIX:*:*)
echo rs6000-ibm-aix
exit 0 ;;
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
exit 0 ;;
DPX/2?00:B.O.S.:*:*)
echo m68k-bull-sysv3
exit 0 ;;
9000/[34]??:4.3bsd:1.*:*)
echo m68k-hp-bsd
exit 0 ;;
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[34678]??:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include
#include
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
if [ ${HP_ARCH} = "hppa2.0w" ]
then
# avoid double evaluation of $set_cc_for_build
test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
then
HP_ARCH="hppa2.0w"
else
HP_ARCH="hppa64"
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
exit 0 ;;
ia64:HP-UX:*:*)
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ia64-hp-hpux${HPUX_REV}
exit 0 ;;
3050*:HI-UX:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
int
main ()
{
long cpu = sysconf (_SC_CPU_VERSION);
/* The order matters, because CPU_IS_HP_MC68K erroneously returns
true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
results, however. */
if (CPU_IS_PA_RISC (cpu))
{
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
default: puts ("hppa-hitachi-hiuxwe2"); break;
}
}
else if (CPU_IS_HP_MC68K (cpu))
puts ("m68k-hitachi-hiuxwe2");
else puts ("unknown-hitachi-hiuxwe2");
exit (0);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
echo unknown-hitachi-hiuxwe2
exit 0 ;;
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
*9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
echo hppa1.0-hp-mpeix
exit 0 ;;
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
i*86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
parisc*:Lites*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit 0 ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit 0 ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*[A-Z]90:*:*:*)
echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
-e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*T3E:*:*:*)
echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
CRAY*SV1:*:*:*)
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
*:UNICOS/mp:*:*)
echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit 0 ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*|*:GNU/FreeBSD:*:*)
# Determine whether the default compiler uses glibc.
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
#if __GLIBC__ >= 2
LIBC=gnu
#else
LIBC=
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
exit 0 ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit 0 ;;
x86:Interix*:3*)
echo i586-pc-interix3
exit 0 ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
exit 0 ;;
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
# UNAME_MACHINE based on the output of uname instead of i386?
echo i586-pc-interix
exit 0 ;;
i*:UWIN*:*)
echo ${UNAME_MACHINE}-pc-uwin
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit 0 ;;
arm*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
mips:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips
#undef mipsel
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mipsel
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
mips64:Linux:*:*)
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#undef CPU
#undef mips64
#undef mips64el
#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
CPU=mips64el
#else
#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
CPU=mips64
#else
CPU=
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
exit 0 ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
exit 0 ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
EV56) UNAME_MACHINE=alphaev56 ;;
PCA56) UNAME_MACHINE=alphapca56 ;;
PCA57) UNAME_MACHINE=alphapca56 ;;
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
exit 0 ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
esac
exit 0 ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
exit 0 ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
exit 0 ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
exit 0 ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit 0 ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
# first see if it will tell us. cd to the root directory to prevent
# problems with other programs or directories called `ld' in the path.
# Set LC_ALL=C to ensure ld outputs messages in English.
ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
| sed -ne '/supported targets:/!d
s/[ ][ ]*/ /g
s/.*supported targets: *//
s/ .*//
p'`
case "$ld_supported_targets" in
elf32-i386)
TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
;;
a.out-i386-linux)
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
exit 0 ;;
coff-i386)
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
exit 0 ;;
"")
# Either a pre-BFD a.out linker (linux-gnuoldld) or
# one that does not give us useful --help.
echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
exit 0 ;;
esac
# Determine whether the default compiler is a.out or elf
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#include
#ifdef __ELF__
# ifdef __GLIBC__
# if __GLIBC__ >= 2
LIBC=gnu
# else
LIBC=gnulibc1
# endif
# else
LIBC=gnulibc1
# endif
#else
#ifdef __INTEL_COMPILER
LIBC=gnu
#else
LIBC=gnuaout
#endif
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
# earlier versions are messed up and put the nodename in both
# sysname and nodename.
echo i386-sequent-sysv4
exit 0 ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i*86:OS/2:*:*)
# If we were able to find `uname', then EMX Unix compatibility
# is probably installed.
echo ${UNAME_MACHINE}-pc-os2-emx
exit 0 ;;
i*86:XTS-300:*:STOP)
echo ${UNAME_MACHINE}-unknown-stop
exit 0 ;;
i*86:atheos:*:*)
echo ${UNAME_MACHINE}-unknown-atheos
exit 0 ;;
i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
i*86:*DOS:*:*)
echo ${UNAME_MACHINE}-pc-msdosdjgpp
exit 0 ;;
i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
fi
exit 0 ;;
i*86:*:5:[78]*)
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
*Pent*|*Celeron) UNAME_MACHINE=i686 ;;
esac
echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
exit 0 ;;
i*86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
&& UNAME_MACHINE=i686
(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
&& UNAME_MACHINE=i686
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit 0 ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
exit 0 ;;
i860:*:4.*:*) # i860-SVR4
if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
else # Add other i860-SVR4 vendors below as they are discovered.
echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
fi
exit 0 ;;
mini*:CTIX:SYS*5:*)
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
mc68k:UNIX:SYSTEM5:3.51m)
echo m68k-convergent-sysv
exit 0 ;;
M680?0:D-NIX:5.3:*)
echo m68k-diab-dnix
exit 0 ;;
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
OS_REL=''
test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
echo powerpc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:ReliantUNIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
exit 0 ;;
*:SINIX-*:*:*)
if uname -p 2>/dev/null >/dev/null ; then
UNAME_MACHINE=`(uname -p) 2>/dev/null`
echo ${UNAME_MACHINE}-sni-sysv4
else
echo ns32k-sni-sysv
fi
exit 0 ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes .
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
*:VOS:*:*)
# From Paul.Green@stratus.com.
echo hppa1.1-stratus-vos
exit 0 ;;
mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
news*:NEWS-OS:6*:*)
echo mips-sony-newsos6
exit 0 ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit 0 ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit 0 ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit 0 ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit 0 ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-5:SUPER-UX:*:*)
echo sx5-nec-superux${UNAME_RELEASE}
exit 0 ;;
SX-6:SUPER-UX:*:*)
echo sx6-nec-superux${UNAME_RELEASE}
exit 0 ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Rhapsody:*:*)
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
exit 0 ;;
*:Darwin:*:*)
case `uname -p` in
*86) UNAME_PROCESSOR=i686 ;;
powerpc) UNAME_PROCESSOR=powerpc ;;
esac
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit 0 ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
if test "$UNAME_PROCESSOR" = "x86"; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
exit 0 ;;
*:QNX:*:4*)
echo i386-pc-qnx
exit 0 ;;
NSR-[DGKLNPTVW]:NONSTOP_KERNEL:*:*)
echo nsr-tandem-nsk${UNAME_RELEASE}
exit 0 ;;
*:NonStop-UX:*:*)
echo mips-compaq-nonstopux
exit 0 ;;
BS2000:POSIX*:*:*)
echo bs2000-siemens-sysv
exit 0 ;;
DS/*:UNIX_System_V:*:*)
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
exit 0 ;;
*:Plan9:*:*)
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
if test "$cputype" = "386"; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
fi
echo ${UNAME_MACHINE}-unknown-plan9
exit 0 ;;
*:TOPS-10:*:*)
echo pdp10-unknown-tops10
exit 0 ;;
*:TENEX:*:*)
echo pdp10-unknown-tenex
exit 0 ;;
KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
echo pdp10-dec-tops20
exit 0 ;;
XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
echo pdp10-xkl-tops20
exit 0 ;;
*:TOPS-20:*:*)
echo pdp10-unknown-tops20
exit 0 ;;
*:ITS:*:*)
echo pdp10-unknown-its
exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <
# include
#endif
main ()
{
#if defined (sony)
#if defined (MIPSEB)
/* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
I don't know.... */
printf ("mips-sony-bsd\n"); exit (0);
#else
#include
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
#else
""
#endif
); exit (0);
#endif
#endif
#if defined (__arm) && defined (__acorn) && defined (__unix)
printf ("arm-acorn-riscix"); exit (0);
#endif
#if defined (hp300) && !defined (hpux)
printf ("m68k-hp-bsd\n"); exit (0);
#endif
#if defined (NeXT)
#if !defined (__ARCHITECTURE__)
#define __ARCHITECTURE__ "m68k"
#endif
int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0);
#endif
#if defined (MULTIMAX) || defined (n16)
#if defined (UMAXV)
printf ("ns32k-encore-sysv\n"); exit (0);
#else
#if defined (CMU)
printf ("ns32k-encore-mach\n"); exit (0);
#else
printf ("ns32k-encore-bsd\n"); exit (0);
#endif
#endif
#endif
#if defined (__386BSD__)
printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
#if defined (i386)
printf ("i386-sequent-dynix\n"); exit (0);
#endif
#if defined (ns32000)
printf ("ns32k-sequent-dynix\n"); exit (0);
#endif
#endif
#if defined (_SEQUENT_)
struct utsname un;
uname(&un);
if (strncmp(un.version, "V2", 2) == 0) {
printf ("i386-sequent-ptx2\n"); exit (0);
}
if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
printf ("i386-sequent-ptx1\n"); exit (0);
}
printf ("i386-sequent-ptx\n"); exit (0);
#endif
#if defined (vax)
# if !defined (ultrix)
# include
# if defined (BSD)
# if BSD == 43
printf ("vax-dec-bsd4.3\n"); exit (0);
# else
# if BSD == 199006
printf ("vax-dec-bsd4.3reno\n"); exit (0);
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# endif
# else
printf ("vax-dec-bsd\n"); exit (0);
# endif
# else
printf ("vax-dec-ultrix\n"); exit (0);
# endif
#endif
#if defined (alliant) && defined (i860)
printf ("i860-alliant-bsd\n"); exit (0);
#endif
exit (1);
}
EOF
$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
# Apollos put the system type in the environment.
test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
# Convex versions that predate uname can use getsysinfo(1)
if [ -x /usr/convex/getsysinfo ]
then
case `getsysinfo -f cpu_type` in
c1*)
echo c1-convex-bsd
exit 0 ;;
c2*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit 0 ;;
c34*)
echo c34-convex-bsd
exit 0 ;;
c38*)
echo c38-convex-bsd
exit 0 ;;
c4*)
echo c4-convex-bsd
exit 0 ;;
esac
fi
cat >&2 < in order to provide the needed
information to handle your system.
config.guess timestamp = $timestamp
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
hostinfo = `(hostinfo) 2>/dev/null`
/bin/universe = `(/bin/universe) 2>/dev/null`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
/bin/arch = `(/bin/arch) 2>/dev/null`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
UNAME_MACHINE = ${UNAME_MACHINE}
UNAME_RELEASE = ${UNAME_RELEASE}
UNAME_SYSTEM = ${UNAME_SYSTEM}
UNAME_VERSION = ${UNAME_VERSION}
EOF
exit 1
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
Pound-2.8/pound.8 0000664 0001750 0001750 00000104103 13275266545 012726 0 ustar roseg roseg .TH POUND "8" "Jan 2010" "pound" "System Manager's Manual"
.SH NAME
pound \- HTTP/HTTPS reverse-proxy and load-balancer
.SH SYNOPSIS
.TP
.B pound
[\fI-v\fR]
[\fI-c\fR]
[\fI-V\fR]
[\fI-f config_file\fR]
[\fI-p pid_file\fR]
.SH DESCRIPTION
.PP
.B Pound
is a reverse-proxy load balancing server. It accepts requests from HTTP/HTTPS
clients and distributes them to one or more Web servers. The HTTPS requests are
decrypted and passed to the back-ends as plain HTTP.
.PP
If more than one back-end server is defined,
.B Pound
chooses one of them randomly, based on defined priorities. By default,
.B Pound
keeps track of associations between clients and back-end servers (sessions).
.SH GENERAL PRINCIPLES
.P
In general
.B Pound
needs three types of objects defined in order to function:
.IR listeners ,
.I services
and
.IR back-ends .
.TP
\fBListeners\fR
A
.I listener
is a definition of how
.B Pound
receives requests from the clients (browsers). Two types of
.I listeners
may be defined: regular HTTP
.I listeners
and HTTPS (HTTP over SSL/TLS)
.IR listeners .
At the very least a
.I listener
must define the address and port to listen on, with additional
requirements for HTTPS
.IR listeners .
.TP
\fBServices\fR
A
.I service
is the definition of how the requests are answered. The
.I services
may be defined within a
.I listener
or at the top level (global). When a request is received
.B Pound
attempts to match them to each
.I service
in turn, starting with the
.I services
defined in the
.I listener
itself and, if needed, continuing with the
.I services
defined at the global level. The
.I services
may define their own conditions as to which requests they can answer:
typically this involves certain URLs (images only, or a certain path)
or specific headers (such as the Host header). A
.I service
may also define a
.I session
mechanism: if defined future requests from a given client will always
be answered by the same
.IR back-end .
.TP
\fBBack-ends\fR
The
.I back-ends
are the actual servers for the content requested. By itself,
.B Pound
supplies no responses - all contents must be received from a "real"
web server. The
.I back-end
defines how the server should be contacted.
.IP
Three types of
.I back-ends
may be defined: a "regular"
.I back-end
which receives requests and returns responses, a "redirect"
.I back-end
in which case
.B Pound
will respond with a redirect response, without accessing any
.I back-end
at all, or an "emergency"
.I back-end
which will be used only if all other backends are "dead".
.IP
Multiple
.I back-ends
may be defined within a
.IR service ,
in which case
.B Pound
will load-balance between the available
.IR back-ends .
.IP
If a
.I back-end
fails to respond it will be considered "dead", in which case
.B Pound
will stop sending requests to it. Dead
.I back-ends
are periodically checked for availability, and once they respond again they
are "resurected" and requests are sent again their way. If no
.I back-ends
are available (none were defined, or all are "dead") then
.B Pound
will reply with "503 Service Unavailable", without checking additional
.IR services .
.IP
The connection between
.B Pound
and the
.I back-ends
is always via HTTP, regardless of the actual protocol used between
.B Pound
and the client.
.SH OPTIONS
Options available (see also below for configuration file options):
.TP
\fB\-v\fR
Verbose mode: error messages will be sent to stdout even if
.B Pound
was configured to log to syslog. This applies only to startup messages, before
.B Pound
puts itself in the background. Normal operational messages will still go to syslog.
.TP
\fB\-V\fR
Print version:
.B Pound
will exit immediately after printing the current version and configuration flags.
.TP
\fB\-c\fR
Check only:
.B Pound
will exit immediately after parsing the configuration file. This may be used for
running a quick syntax check before actually activating a server.
.TP
\fB\-f\fR config_file
Location of the configuration file (see below for a full description of the format).
Default:
.I /usr/local/etc/pound.cfg
.TP
\fB\-p\fR pid_file
Location of the pid file.
.B Pound
will write its own pid into this file. Normally this is used for shell
scripts that control starting and stopping of the daemon.
Default:
.I /var/run/pound.pid
.PP
In general, any number of back-end servers may be specified. Use the priority to
affect the load distribution among unequal-performance servers.
.PP
One (or more) copies of
.B Pound
should be started at boot time. Use "big iron" if you expect heavy loads: while
.B Pound
is as light-weight as I know how to make it, with a lot of simultaneous requests it
will use quite a bit of CPU and memory. Multiple CPUs are your friend.
.SH "CONFIGURATION FILE"
Each line in the file is considered a complete configuration directive. The directives
are case-insensitive. Empty lines or lines starting in '#' are ignored. There are three
types of directives:
.B global
directives (they affect the settings for the entire program instance),
.B listener
directives (they define which requests
.B Pound
will listen for), and
.B service
directives (they affect only a specific group of requests).
.SH "GLOBAL DIRECTIVES"
Global directives may appear anywhere within the configuration file, though it is
customary for them to be at the start. They may appear in any order.
.TP
\fBUser\fR "user_name"
Specify the user
.B Pound
will run as (must be defined in \fI/etc/passwd\fR).
.TP
\fBGroup\fR "group_name"
Specify the group
.B Pound
will run as (must be defined in \fI/etc/group\fR).
.TP
\fBRootJail\fR "directory_path_and_name"
Specify the directory that
.B Pound
will chroot to at runtime. Please note that OpenSSL requires access to /dev/urandom,
so make sure you create a device by that name, accessible from the root jail
directory.
.B Pound
may also require access to
.I /dev/syslog
or similar.
.TP
\fBDaemon\fR 0|1
Have
.B Pound
run in the foreground (if 0) or as a daemon (if 1). By default
.B Pound
runs as a daemon (detaches itself from the controlling terminal and
puts itself in the background). By specifying this option you can force
.B Pound
to work like a regular process. Useful for debugging or if you want to
use something like \fIdaemontools\fR.
.TP
\fBThreads\fR nnn
How many worker threads
.B Pound
should use. Default: 128. Tune this parameter to improve performance.
If you set it too high,
.B Pound
will use a lot memory, and some CPU will be wasted on context switches.
If you set it too low requests may be served with some delay. Experiment
to find the optimal value for your installation.
.TP
\fBLogFacility\fR value
Specify the log facility to use.
.I value
(default: daemon) must be one of the symbolic facility names defined in
\fIsyslog.h\fR. This facility shall be used for logging. Using a - for
the facility name causes
.B Pound
to log to stdout/stderr.
.TP
\fBLogLevel\fR value
Specify the logging level: 0 for no logging, 1 (default) for regular
logging, 2 for extended logging (show chosen backend server as well),
3 for Apache-like format (Combined Log Format with Virtual Host), 4
(same as 3 but without the virtual host information) and 5 (same as 4
but with information about the
.I Service
and
.I BackEnd
used).
This value can be overridden for specific listeners.
.TP
\fBIgnoreCase\fR 0|1
Ignore case when matching URLs (default: 0). This value can be
overridden for specific services.
.TP
\fBAlive\fR value
Specify how often
.B Pound
will check for resurected back-end hosts (default: 30 seconds). In
general, it is a good idea to set this as low as possible - it
will find resurected hosts faster. However, if you set it too
low it will consume resources - so beware.
.TP
\fBClient\fR value
Specify for how long
.B Pound
will wait for a client request (default: 10 seconds). After this
long has passed without the client sending any data
.B Pound
will close the connection. Set it higher if your clients
time-out on a slow network or over-loaded server, lower if you
start getting DOS attacks or run into problems with IE clients.
This value can be overridden for specific listeners.
.TP
\fBTimeOut\fR value
How long should
.B Pound
wait for a response from the back-end (in seconds). Default: 15 seconds.
This value can be overridden for specific back-ends.
.TP
\fBConnTO\fR value
How long should
.B Pound
wait for a connection to the back-end (in seconds). Default: the
.B TimeOut
value. This value can be overridden for specific back-ends.
.TP
\fBGrace\fR value
How long should
.B Pound
continue to answer existing connections after a receiving and INT or HUP
signal (default: 30 seconds). The configured listeners are closed
immediately. You can bypass this behaviour by stopping
.B Pound
with a TERM or QUIT signal, in which case the program exits without any
delay.
.TP
\fBSSLEngine\fR "name"
Use an OpenSSL hardware acceleration card called \fIname\fR. Available
only if OpenSSL-engine is installed on your system.
.TP
\fBECDHcurve\fR "name"
Use the named curve for elliptical curve encryption (default: prime256v1).
.TP
\fBControl\fR "/path/to/socket"
Set the control socket path. If not defined
.B Pound
does not listen for any commands. The commands may be issued by using
the
.I poundctl(8)
program.
.TP
\fBInclude\fR "/path/to/file"
Include the file as though it were part of the configuration file.
.TP
\fBAnonymise\fR
Replace the last byte of the client address with 0 for logging purposes.
Default: log the client address in full.
.SH "HTTP Listener"
An HTTP listener defines an address and port that
.B Pound
will listen on for HTTP requests. All configuration directives enclosed
between
.I ListenHTTP
and
.I End
are specific to a single HTTP listener. At the very least you must specify
and address and a port for each listener. The following directives are
available:
.TP
\fBAddress\fR address
The address that
.B Pound
will listen on. This can be a numeric IP address, or a symbolic host name
that must be resolvable at run-time. This is a
.B mandatory
parameter. The address 0.0.0.0 may be used as an alias for 'all available
addresses on this machine', but this practice is strongly discouraged, as
it will interfere with the rewriting mechanisms (see below).
.TP
\fBPort\fR port
The port number that
.B Pound
will listen on. This is a
.B mandatory
parameter.
.TP
\fBxHTTP\fR value
Defines which HTTP verbs are accepted. The possible values are:
.IP
.I 0
(default) accept only standard HTTP requests (GET, POST, HEAD).
.IP
.I 1
additionally allow extended HTTP requests (PUT, PATCH, DELETE).
.IP
.I 2
additionally allow standard WebDAV verbs (LOCK, UNLOCK, PROPFIND,
PROPPATCH, SEARCH, MKCOL, MOVE, COPY, OPTIONS, TRACE, MKACTIVITY,
CHECKOUT, MERGE, REPORT).
.IP
.I 3
additionally allow MS extensions WebDAV verbs (SUBSCRIBE, UNSUBSCRIBE,
NOTIFY, BPROPFIND, BPROPPATCH, POLL, BMOVE, BCOPY, BDELETE, CONNECT).
.IP
.I 4
additionally allow MS RPC extensions verbs (RPC_IN_DATA, RPC_OUT_DATA).
.TP
\fBClient\fR value
Override the global
.I Client
time-out value.
.TP
\fBCheckURL\fR "pattern to match"
Define a pattern that must be matched by each request sent to this
listener. A request that does not match is considered to be illegal.
By default
.B Pound
accepts all requests (i.e. the pattern is ".*"), but you are free to
limit it to something more reasonable. Please note that this applies
only to the request path -
.B Pound
will still check that the request is syntactically correct.
.TP
\fBErr414\fR "filename"
A file with the text to be displayed if an Error 414 occurs.
Default: "Request URI is too long.".
.TP
\fBErr500\fR "filename"
A file with the text to be displayed if an Error 500 occurs.
Default: "An internal server error occurred. Please try again later.".
.TP
\fBErr501\fR "filename"
A file with the text to be displayed if an Error 501 occurs.
Default: "This method may not be used.".
.TP
\fBErr503\fR "filename"
A file with the text to be displayed if an Error 503 occurs.
Default: "The service is not available. Please try again later.".
.TP
\fBMaxRequest\fR nnn
Request maximal size. All requests will be limited to these many bytes. If
a request contains more data than allowed an error 414 is returned. Default:
unlimited.
.TP
\fBHeadRemove\fR "header pattern"
Remove certain headers from the incoming requests. All occurences of the
matching specified header will be removed. Please note that this filtering
is done prior to other checks (such as \fIHeadRequire\fR or \fIHeadDeny\fR),
so you should not try to check for these headers in later matches. Multiple
directives may be specified in order to remove more than one header, and
the header itself may be a regular pattern (though this should be used with
caution).
.TP
\fBAddHeader\fR "header: to add"
Add the defined header to the request passed to the back-end server. The header
is added verbatim. Use multiple \fIAddHeader\fR directives if you need to add more
than one header.
.TP
\fBRewriteLocation\fR 0|1|2
If 1 force
.B Pound
to change the Location: and Content-location: headers in responses. If they
point to the back-end itself or to the listener (but with the wrong protocol)
the response will be changed to show the virtual host in the request. Default:
1 (active). If the value is set to 2 only the back-end address is compared;
this is useful for redirecting a request to an HTTPS listener on
the same server as the HTTP listener.
.TP
\fBRewriteDestination\fR 0|1
If 1 force
.B Pound
to change the Destination: header in requests. The header is changed to point
to the back-end itself with the correct protocol. Default: 0.
.TP
\fBLogLevel\fR value
Override the global
.I LogLevel
value.
.TP
\fBService\fR [ "name" ]
This defines a private service (see below for service definition syntax). This
service will be used only by this listener. The service may be optionally
named, with the name showing in the
.I poundctl
listings.
.SH "HTTPS Listener"
An HTTPS listener defines an address and port that
.B Pound
will listen on for HTTPS requests. All configuration directives enclosed
between
.I ListenHTTPS
and
.I End
are specific to a single HTTPS listener. At the very least you must specify
and address, a port and a server certificate for each listener. All directives
defined for HTTP listeners are applicable to HTTPS listeners as well. The
following additional directives are also available:
.TP
\fBCert\fR "certificate file"
Specify the server certificate. The
.I certificate file
is the file containing the certificate, possibly a certificate chain and the signature
for this server. This directive is
.B mandatory
for HTTPS listeners.
.IP
Please note that multiple
.I Cert
directives are allowed if your OpenSSL version supports SNI. In such cases,
the first directive is the default certificate, with additional certificates
used if the client requests them.
.IP
The ordering of the directives is important: the first certificate where the CN
matches the client request will be used, so put your directives in the
most-specific-to-least specific order (i.e. wildcard certificates
.B after
host-specific certificates).
.IP
.I Cert
directives
.B must
precede all other SSL-specific directives.
.TP
\fBClientCert\fR 0|1|2|3 depth
Ask for the client's HTTPS certificate: 0 - don't ask (default), 1 - ask,
2 - ask and fail if no certificate was presented, 3 - ask but do not verify.
.I Depth
is the depth of verification for a client certificate (up to 9). The default
depth limit is 9, allowing for the peer certificate and additional 9 CA
certificates that must be verified.
.TP
\fBDisable\fR SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2
Disable the protocol \fBand all lower protocols as well\fR.
This is due to a limitation in OpenSSL, which does not support disabling a single
protocol. For example,
.I Disable TLSv1
would disable SSLv2, SSLv3 and TLSv1, thus allowing only TLSv1_1 and TLSv1_2.
.TP
\fBCiphers\fR "acceptable:cipher:list"
This is the list of ciphers that will be accepted by the SSL connection; it is a
string in the same format as in OpenSSL
.I ciphers(1)
and
.I SSL_CTX_set_cipher_list(3).
.TP
\fBSSLHonorCipherOrder\fR 0|1
If this value is 1, the server will broadcast a preference to use \fBCiphers\fR in
the order supplied in the \fBCiphers\fR directive. If the value is 0, the server
will treat the Ciphers list as the list of Ciphers it will accept, but no preference
will be indicated. Default value is 0.
.TP
\fBSSLAllowClientRenegotiation\fR 0|1|2
If this value is 0, client initiated renegotiation will be disabled. This will
mitigate DoS exploits based on client renegotiation, regardless of the patch status
of clients and servers related to "Secure renegotiation". If the value is 1, secure
renegotiation is supported. If the value is 2, insecure renegotiation is supported,
with unpatched clients. \fBThis can lead to a DoS and a Man in the Middle attack!\fR
The default value is 0.
.TP
\fBCAlist\fR "CAcert_file"
Set the list of "trusted" CA's for this server. The CAcert_file is a file containing
a sequence of CA certificates (PEM format). The names of the defined CA certificates
will be sent to the client on connection.
.TP
\fBVerifyList\fR "Verify_file"
Set the CA (Certificate Authority). The Verify_file is a file that contains the CA
root certificates (in PEM format).
.IP
.IR "Please note":
there is an important difference between the CAlist and the VerifyList. The
CAlist tells the client (browser) which client certificates it should send. The
VerifyList defines which CAs are actually used for the verification of the
returned certificate.
.TP
\fBCRLlist\fR "CRL_file"
Set the CRL (Certificate Revocation List) file. The CRL_file is a file that contains
the CRLs (in PEM format).
.TP
\fBNoHTTPS11\fR 0|1|2
Behave like an HTTP/1.0 server for HTTPS clients. If this value is
0 disable the check. If the value is 1 do not allow multiple
requests on SSL connections. If the value is 2 (default) disable multiple
requests on SSL connections only for MSIE clients. Required
work-around for a bug in certain versions of IE.
.SH "Service"
A service is a definition of which back-end servers
.B Pound
will use to reply to incoming requests. A service may be defined as part
of a listener (in which case it will be used only by that listener), or
globally (which makes it available to all listeners).
.B Pound
will always try the private services in the order defined, followed by
the global ones.
.P
All configuration directives enclosed between
.I Service
and
.I End
are specific to a single service. The following directives are available:
.TP
\fBURL\fR "pattern"
Match the incoming request. If a request fails to match than this service
will be skipped and next one tried. If all services fail to match
.B Pound
returns an error. You may define multiple
.I URL
conditions per service, in which case
.B all
patterns must match. If no
.I URL
was defined then all requests match. The matching is by default case-sensitive,
but this can be overridden by specifying
.B IgnoreCase 1
.TP
\fBIgnoreCase\fR 0|1
Override the global
.B IgnoreCase
setting.
.TP
\fBHeadRequire\fR "pattern"
The request must contain at least on header matching the given pattern.
Multiple
.I HeadRequire
directives may be defined per service, in which case all of them must
be satisfied.
.TP
\fBHeadDeny\fR "pattern"
The request may
.B not
contain any header matching the given pattern. Multiple
.I HeadDeny
directives may be defined per service, in which case all of them must be satisfied.
.IP
.IR "Please note":
if the listener defined a
.I HeadRemove
directive, the matching headers are removed
.B before
the service matching is attempted.
.TP
\fBDisabled\fR 0|1
Start
.B Pound
with this service disabled (1) or enabled (0). If started as disabled, the
service can be later enabled with
.I poundctl
(8).
.TP
\fBBackEnd\fR
Directives enclosed between a
.I BackEnd
and
the following
.I End
directives define a single back-end server (see below for details). You may define
multiple back-ends per service, in which case
.B Pound
will attempt to load-balance between them.
.TP
\fBRedirect\fR [code] "url"
This is a special type of back-end. Instead of sending the request to a back-end
.B Pound
replies immediately with a redirection to the given URL. You may define multiple
redirectors in a service, as well as mixing them with regular back-ends.
.IP
The address the client is redirected to is determined by the actual
.I url
you specify: if it is a "pure" host (i.e. with no path) then the client will be
redirected to the host you specified, with the original request path appended. If
your
.I url
does contain a path then the request path is ignored.
.IP
Examples: if you specified
.br
.br
Redirect "http://abc.example"
.br
.br
and the client requested
.I http://xyz/a/b/c
then it will be redirected to
.IR "http://abc.example/a/b/c",
but if you specified
.br
.br
Redirect "http://abc.example/index.html"
.br
.br
it will be sent to
.IR "http://abc.example/index.html".
.IP
.IR "Technical note":
in an ideal world
.B Pound
should reply with a "307 Temporary Redirect" status. Unfortunately, that is not
yet supported by all clients (in particular HTTP 1.0 ones), so
.B Pound
currently replies by default with a "302 Found" instead. You may override this
behaviour by specifying the code to be used (301, 302 or 307).
.TP
\fBEmergency\fR
Directives enclosed between an
.I Emergency
and
the following
.I End
directives define an emergency back-end server (see below for details). You may define
only one emergency server per service, which
.B Pound
will attempt to use if all backends are down.
.TP
\fBSession\fR
Directives enclosed between a
.I Session
and
the following
.I End
directives define a session-tracking mechanism for the current service. See below
for details.
.SH "BackEnd"
A back-end is a definition of a single back-end server
.B Pound
will use to reply to incoming requests. All configuration directives enclosed between
.I BackEnd
and
.I End
are specific to a single service. The following directives are available:
.TP
\fBAddress\fR address
The address that
.B Pound
will connect to. This can be a numeric IP address, or a symbolic host name
that must be resolvable at run-time. If the name cannot be resolved to a valid
address,
.B Pound
will assume that it represents the path for a Unix-domain socket. This is a
.B mandatory
parameter.
.TP
\fBPort\fR port
The port number that
.B Pound
will connect to. This is a
.B mandatory
parameter for non Unix-domain back-ends.
.TP
\fBHTTPS\fR
The back-end is using HTTPS.
.TP
\fBCert\fR "certificate file"
Specify the certificate that
.B Pound
will use as a client. The
.I certificate file
is the file containing the certificate, possibly a certificate chain and the signature.
This directive may appear only after the
.I HTTPS
directive.
.TP
\fBDisable\fR SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2
Disable the protocol \fBand all lower protocols as well\fR.
This is due to a limitation in OpenSSL, which does not support disabling a single
protocol. For example,
.I Disable TLSv1
would disable SSLv2, SSLv3 and TLSv1, thus allowing only TLSv1_1 and TLSv1_2.
This directive may appear only after the
.I HTTPS
directive.
.TP
\fBCiphers\fR "acceptable:cipher:list"
This is the list of ciphers that will be accepted by the SSL connection; it is a
string in the same format as in OpenSSL
.I ciphers(1)
and
.I SSL_CTX_set_cipher_list(3).
This directive may appear only after the
.I HTTPS
directive.
.TP
\fBPriority\fR val
The priority of this back-end (between 1 and 9, 5 is default). Higher priority
back-ends will be used more often than lower priority ones, so you should
define higher priorities for more capable servers.
.TP
\fBTimeOut\fR val
Override the global
.I TimeOut
value.
.TP
\fBConnTO\fR val
Override the global
.I ConnTO
value.
.TP
\fBHAport\fR [ address ] port
A port (and optional address) to be used for server function checks. See below
the "High Availability" section for a more detailed discussion. By default
.B Pound
uses the same address as the back-end server, but you may use a separate address
if you wish. This directive applies only to non Unix-domain servers.
.TP
\fBDisabled\fR 0|1
Start
.B Pound
with this back-end disabled (1) or enabled (0). If started as disabled, the
back-end can be later enabled with
.I poundctl
(8).
.SH "Emergency"
The emergency server will be used once all existing back-ends are "dead".
All configuration directives enclosed between
.I Emergency
and
.I End
are specific to a single service. The following directives are available:
.TP
\fBAddress\fR address
The address that
.B Pound
will connect to. This can be a numeric IP address, or a symbolic host name
that must be resolvable at run-time. If the name cannot be resolved to a valid
address,
.B Pound
will assume that it represents the path for a Unix-domain socket. This is a
.B mandatory
parameter.
.TP
\fBPort\fR port
The port number that
.B Pound
will connect to. This is a
.B mandatory
parameter for non Unix-domain back-ends.
.SH "Session"
Defines how a service deals with possible HTTP sessions. All configuration
directives enclosed between
.I Session
and
.I End
are specific to a single service. Once a sessions is identified,
.B Pound
will attempt to send all requests within that session to the same back-end
server.
.PP
The following directives are available:
.TP
\fBType\fR IP|BASIC|URL|PARM|COOKIE|HEADER
What kind of sessions are we looking for: IP (the client address), BASIC (basic
authentication), URL (a request parameter), PARM (a URI parameter), COOKIE (a
certain cookie), or HEADER (a certain request header).
This is a
.B mandatory
parameter.
.TP
\fBTTL\fR seconds
How long can a session be idle (in seconds). A session that has been idle for
longer than the specified number of seconds will be discarded.
This is a
.B mandatory
parameter.
.TP
\fBID\fR "name"
The session identifier. This directive is permitted only for sessions of type
URL (the name of the request parameter we need to track), COOKIE (the name of
the cookie) and HEADER (the header name).
.PP
See below for some examples.
.SH HIGH-AVAILABILITY
.B Pound
attempts to keep track of active back-end servers, and will temporarily disable
servers that do not respond (though not necessarily dead: an overloaded server
that
.B Pound
cannot establish a connection to will be considered dead). However, every
.I Alive
seconds, an attempt is made to connect to the dead servers in case they have become
active again. If this attempt succeeds, connections will be initiated to them again.
.PP
In general it is a good idea to set this time interval as low as is consistent with
your resources in order to benefit from resurected servers at the earliest possible
time. The default value of 30 seconds is probably a good choice.
.PP
The clients that happen upon a dead backend server will just receive a
.I "503 Service Unavailable"
message.
.PP
The
.I HAport
parameter specifies an additional port (and optionally an address)
that is used only for viability checks: if this port is specified in a
.I BackEnd
directive,
.B Pound
will attempt periodically (every
.I Alive
seconds) to connect to this port. If the port does not respond the server is considered dead.
.B "It never makes sense to have the"
.I HAport
.B "identical to the main back-end port:"
this would only generate extra, unncecessary activity (CPU, network traffic) for no good
reason whatsoever. The
.I HAport
is meant for applications that offer an additional health monitoring port or for installations
that wish to take servers off-line in a controlled manner.
.PP
By default the address of the
.I HAport
health monitor is the same as that of the
back-end server. You may specify a different address though, for example if you have
a monitoring program running on another host.
.SH HTTPS HEADERS
If a client browser connects to
.B Pound
via HTTPS and if it presents a client certificate
.B Pound
adds the following headers to the request it issues to the server:
.TP
\fBX-SSL-Subject\fR
Details about the certificate owner.
.TP
\fBX-SSL-Issuer\fR
Details about the certificate issuer (Certificate Authority).
.TP
\fBX-SSL-notBefore\fR
Starting date of certificate validity.
.TP
\fBX-SSL-notAfter\fR
Ending date of certificate validity.
.TP
\fBX-SSL-serial\fR
Certificate serial number (decimal).
.TP
\fBX-SSL-cipher\fR
The cipher currently in use.
.TP
\fBX-SSL-certificate\fR
The full client certificate (PEM-format multi-line)
.PP
It is the application's responsibility to actually use these
headers - Pound just passes this information without checking
it in any way (except for signature and encryption correctness).
.SH SECURITY
.PP
In general,
.B Pound
does not read or write to the hard-disk. The exceptions are reading the configuration file
and (possibly) the server certificate file(s) and error message(s), which are opened read-only
on startup, read,
and closed, and the pid file which is opened on start-up, written to and immediately closed.
Following this there is no disk access whatsoever, so using a RootJail directive is only
for extra security bonus points.
.PP
.B Pound
tries to sanitise all HTTP/HTTPS requests: the request itself, the headers and the contents
are checked for conformance to the RFC's and only valid requests are passed to the back-end
servers. This is not absolutely fool-proof - as the recent Apache problem with chunked
transfers demonstrated. However, given the current standards, this is the best that can
be done - HTTP is an inherently weak protocol.
.SH ADDITIONAL NOTES
.B Pound
uses the system log for messages (default facility LOG_DAEMON). The format is very similar to
other web servers, so that if you want to use a log tool:
.TP
fgrep pound /var/log/messages | your_log_tool
.PP
Translating HTTPS to HTTP is an iffy proposition: no client information is passed to
the server itself (certificates, etc) and the backend server may be misled if it
uses absolute URLs. A patch for \fIZope\fR is included in the distribution to address
this issue - for other Web servers you are on your own. May the source be with you.
.PP
.B Pound
deals with (and sanitizes) HTTP/1.1 requests. Thus even if you have an HTTP/1.0 server,
a single connection to an HTTP/1.1 client is kept, while the connection to the back-end
server is re-opened as necessary.
.PP
.B Pound
attempts to resolve the names of the hosts that appear in various requests and/or responses.
That means it need a functioning resolver of some kind (be it /etc/hosts, DNS or something
else).
.SH EXAMPLES
To translate HTTPS requests to a local HTTP server (assuming your network address
is 123.123.123.123):
.IP
ListenHTTPS
.br
Address 1.2.3.4
.br
Port 443
.br
Cert "/etc/pound/server.pem"
.br
.br
Service
.br
BackEnd
.br
Address 127.0.0.1
.br
Port 80
.br
End
.br
End
.br
End
.PP
To distribute the HTTP/HTTPS requests to three Web servers, where the third one
is a newer and faster machine:
.IP
ListenHTTP
.br
Address 123.123.123.123
.br
Port 80
.br
End
.br
ListenHTTPS
.br
Address 1.2.3.4
.br
Port 443
.br
Cert "/etc/pound/server.pem"
.br
End
.br
.br
Service
.br
BackEnd
.br
Address 192.168.0.10
.br
Port 80
.br
End
.br
BackEnd
.br
Address 192.168.0.11
.br
Port 80
.br
End
.br
BackEnd
.br
Address 192.168.0.12
.br
Port 80
.br
Priority 3
.br
End
.br
End
.PP
To separate between image requests and other Web content and send all requests
for a specific URL to a secure server:
.IP
ListenHTTP
.br
Address 123.123.123.123
.br
Port 80
.br
End
.br
.br
# Images server(s)
.br
Service
.br
URL ".*.(jpg|gif)"
.br
BackEnd
.br
Address 192.168.0.12
.br
Port 80
.br
End
.br
End
.br
.br
# redirect all requests for /forbidden
.br
Service
.br
Url "/forbidden.*"
.br
Redirect "https://xyzzy.com"
.br
End
.br
.br
# Catch-all server(s)
.br
Service
.br
BackEnd
.br
Address 192.168.0.10
.br
Port 80
.br
End
.br
BackEnd
.br
Address 192.168.0.11
.br
Port 80
.br
End
.br
Session
.br
Type BASIC
.br
TTL 300
.br
End
.br
End
.PP
Here is a more complex example: assume your static images (GIF/JPEG) are to be served
from a single back-end 192.168.0.10. In addition, 192.168.0.11 is to do the
hosting for www.myserver.com with URL-based sessions, and 192.168.0.20 (a 1GHz PIII)
and 192.168.0.21 (800Mhz Duron) are for all other requests (cookie-based sessions).
The logging will be done by the back-end servers. The configuration file may look like this:
.IP
User "nobody"
.br
Group "nogroup"
.br
RootJail "/var/pound/jail"
.br
Alive 60
.br
LogLevel 0
.br
.br
# Main listening ports
.br
ListenHTTP
.br
Address 1.2.3.4
.br
Port 80
.br
Client 10
.br
End
.br
ListenHTTPS
.br
Address 1.2.3.4
.br
Port 443
.br
Cert "/etc/pound/pound.pem"
.br
Client 20
.br
End
.br
.br
# Image server
.br
Service
.br
URL ".*.(jpg|gif)"
.br
BackEnd
.br
Address 192.168.0.10
.br
Port 80
.br
End
.br
End
.br
.br
# Virtual host www.myserver.com
.br
Service
.br
URL ".*sessid=.*"
.br
HeadRequire "Host:.*www.myserver.com.*"
.br
BackEnd
.br
Address 192.168.0.11
.br
Port 80
.br
End
.br
Session
.br
Type URL
.br
ID "sessid"
.br
TTL 120
.br
End
.br
End
.br
.br
# Everybody else
.br
Service
.br
BackEnd
.br
Address 192.168.0.20
.br
Port 80
.br
Priority 5
.br
End
.br
BackEnd
.br
Address 192.168.0.21
.br
Port 80
.br
Priority 4
.br
End
.br
Session
.br
Type COOKIE
.br
ID "userid"
.br
TTL 180
.br
End
.br
End
.br
.SH FILES
.TP
\fI/var/run/pound.nnn\fR
this is where
.B Pound
will attempt to record its process id.
.TP
\fI/usr/local/etc/pound.cfg\fR
the default configuration file (the location may be changed when compiling - see the
F_CONF flag in the Makefile).
.TP
\fI/usr/local/etc/pound/cert.pem\fR
the certificate file(s) for HTTPS. The location must be defined in the configuration
file - this is only a suggestion. The file must contain a PEM-encoded certificate,
optionally a certificate chain from a known Certificate Authority to your server certificate
and a PEM-encoded private key (not password protected). See
.I OpenSSL(1)
for details. This file should be well protected, lest someone gets your server
private key.
.SH AUTHOR
Written by Robert Segall, Apsis GmbH.
.SH "REPORTING BUGS"
Report bugs to .
.SH COPYRIGHT
Copyright \(co 2002-2010 Apsis GmbH.
.br
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Pound-2.8/http.c 0000664 0001750 0001750 00000174364 13275266545 012653 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#include "pound.h"
/* HTTP error replies */
static char *h500 = "500 Internal Server Error",
*h501 = "501 Not Implemented",
*h503 = "503 Service Unavailable",
*h414 = "414 Request URI too long",
*h400 = "Bad Request";
static char *err_response = "HTTP/1.0 %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\nExpires: now\r\nPragma: no-cache\r\nCache-control: no-cache,no-store\r\n\r\n%s";
/*
* Reply with an error
*/
static void
err_reply(BIO *const c, const char *head, const char *txt)
{
BIO_printf(c, err_response, head, strlen(txt), txt);
BIO_flush(c);
return;
}
/*
* Reply with a redirect
*/
static void
redirect_reply(BIO *const c, const char *url, const int code)
{
char rep[MAXBUF], cont[MAXBUF], safe_url[MAXBUF], *code_msg;
int i, j;
switch(code) {
case 301:
code_msg = "Moved Permanently";
break;
case 307:
code_msg = "Temporary Redirect";
break;
default:
code_msg = "Found";
break;
}
/*
* Make sure to return a safe version of the URL (otherwise CSRF becomes a possibility)
*/
memset(safe_url, 0, MAXBUF);
for(i = j = 0; i < MAXBUF && j < MAXBUF && url[i]; i++)
if(isalnum(url[i]) || url[i] == '_' || url[i] == '.' || url[i] == ':' || url[i] == '/'
|| url[i] == '?' || url[i] == '&' || url[i] == ';' || url[i] == '-' || url[i] == '=')
safe_url[j++] = url[i];
else {
sprintf(safe_url + j, "%%%02x", url[i]);
j += 3;
}
snprintf(cont, sizeof(cont),
"RedirectRedirect
You should go to %s
",
safe_url, safe_url);
snprintf(rep, sizeof(rep),
"HTTP/1.0 %d %s\r\nLocation: %s\r\nContent-Type: text/html\r\nContent-Length: %d\r\n\r\n",
code, code_msg, safe_url, (int)strlen(cont));
BIO_write(c, rep, strlen(rep));
BIO_write(c, cont, strlen(cont));
BIO_flush(c);
return;
}
/*
* Read and write some binary data
*/
static int
copy_bin(BIO *const cl, BIO *const be, LONG cont, LONG *res_bytes, const int no_write)
{
char buf[MAXBUF];
int res;
while(cont > L0) {
if((res = BIO_read(cl, buf, cont > MAXBUF? MAXBUF: cont)) < 0)
return -1;
else if(res == 0)
return -2;
if(!no_write)
if(BIO_write(be, buf, res) != res)
return -3;
cont -= res;
if(res_bytes)
*res_bytes += res;
}
if(!no_write)
if(BIO_flush(be) != 1)
return -4;
return 0;
}
/*
* Get a "line" from a BIO, strip the trailing newline, skip the input stream if buffer too small
* The result buffer is NULL terminated
* Return 0 on success
*/
static int
get_line(BIO *const in, char *const buf, const int bufsize)
{
char tmp;
int i, n_read, seen_cr;
memset(buf, 0, bufsize);
for(i = 0, seen_cr = 0; i < bufsize - 1; i++)
switch(BIO_read(in, &tmp, 1)) {
case -2:
/* BIO_gets not implemented */
return -1;
case 0:
case -1:
return 1;
default:
if(seen_cr)
if(tmp != '\n') {
/* we have CR not followed by NL */
do {
if(BIO_read(in, &tmp, 1) < 0)
return 1;
} while(tmp != '\n');
return 1;
} else {
buf[i - 1] = '\0';
return 0;
}
if(!iscntrl(tmp) || tmp == '\t') {
buf[i] = tmp;
continue;
}
if(tmp == '\r') {
seen_cr = 1;
continue;
}
if(tmp == '\n') {
/* line ends in NL only (no CR) */
buf[i] = 0;
return 0;
}
/* all other control characters cause an error */
do {
if(BIO_read(in, &tmp, 1) < 0)
return 1;
} while(tmp != '\n');
return 1;
}
/* line too long */
do {
if(BIO_read(in, &tmp, 1) < 0)
return 1;
} while(tmp != '\n');
return 1;
}
/*
* Strip trailing CRLF
*/
static int
strip_eol(char *lin)
{
while(*lin)
if(*lin == '\n' || (*lin == '\r' && *(lin + 1) == '\n')) {
*lin = '\0';
return 1;
} else
lin++;
return 0;
}
/*
* Copy chunked
*/
static int
copy_chunks(BIO *const cl, BIO *const be, LONG *res_bytes, const int no_write, const LONG max_size)
{
char buf[MAXBUF];
LONG cont, tot_size;
regmatch_t matches[2];
int res;
for(tot_size = 0L;;) {
if((res = get_line(cl, buf, MAXBUF)) < 0) {
logmsg(LOG_NOTICE, "(%lx) chunked read error: %s", pthread_self(), strerror(errno));
return -1;
} else if(res > 0)
/* EOF */
return 0;
if(!regexec(&CHUNK_HEAD, buf, 2, matches, 0))
cont = STRTOL(buf, NULL, 16);
else {
/* not chunk header */
logmsg(LOG_NOTICE, "(%lx) bad chunk header <%s>: %s", pthread_self(), buf, strerror(errno));
return -2;
}
if(!no_write)
if(BIO_printf(be, "%s\r\n", buf) <= 0) {
logmsg(LOG_NOTICE, "(%lx) error write chunked: %s", pthread_self(), strerror(errno));
return -3;
}
tot_size += cont;
if(max_size > L0 && tot_size > max_size) {
logmsg(LOG_WARNING, "(%lx) chunk content too large", pthread_self);
return -4;
}
if(cont > L0) {
if(copy_bin(cl, be, cont, res_bytes, no_write)) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error copy chunk cont: %s", pthread_self(), strerror(errno));
return -4;
}
} else
break;
/* final CRLF */
if((res = get_line(cl, buf, MAXBUF)) < 0) {
logmsg(LOG_NOTICE, "(%lx) error after chunk: %s", pthread_self(), strerror(errno));
return -5;
} else if(res > 0) {
logmsg(LOG_NOTICE, "(%lx) unexpected EOF after chunk", pthread_self());
return -5;
}
if(buf[0])
logmsg(LOG_NOTICE, "(%lx) unexpected after chunk \"%s\"", pthread_self(), buf);
if(!no_write)
if(BIO_printf(be, "%s\r\n", buf) <= 0) {
logmsg(LOG_NOTICE, "(%lx) error after chunk write: %s", pthread_self(), strerror(errno));
return -6;
}
}
/* possibly trailing headers */
for(;;) {
if((res = get_line(cl, buf, MAXBUF)) < 0) {
logmsg(LOG_NOTICE, "(%lx) error post-chunk: %s", pthread_self(), strerror(errno));
return -7;
} else if(res > 0)
break;
if(!no_write)
if(BIO_printf(be, "%s\r\n", buf) <= 0) {
logmsg(LOG_NOTICE, "(%lx) error post-chunk write: %s", pthread_self(), strerror(errno));
return -8;
}
if(!buf[0])
break;
}
if(!no_write)
if(BIO_flush(be) != 1) {
logmsg(LOG_NOTICE, "(%lx) copy_chunks flush error: %s", pthread_self(), strerror(errno));
return -4;
}
return 0;
}
static int err_to = -1;
typedef struct {
int timeout;
RENEG_STATE *reneg_state;
} BIO_ARG;
/*
* Time-out for client read/gets
* the SSL manual says not to do it, but it works well enough anyway...
*/
static long
bio_callback(BIO *const bio, const int cmd, const char *argp, int argi, long argl, long ret)
{
BIO_ARG *bio_arg;
struct pollfd p;
int to, p_res, p_err;
if(cmd != BIO_CB_READ && cmd != BIO_CB_WRITE)
return ret;
/* a time-out already occured */
if((bio_arg = (BIO_ARG*)BIO_get_callback_arg(bio))==NULL)
return ret;
if((to = bio_arg->timeout * 1000) < 0) {
errno = ETIMEDOUT;
return -1;
}
/* Renegotiations */
/* logmsg(LOG_NOTICE, "RENEG STATE %d", bio_arg->reneg_state==NULL?-1:*bio_arg->reneg_state); */
if (bio_arg->reneg_state != NULL && *bio_arg->reneg_state == RENEG_ABORT) {
logmsg(LOG_NOTICE, "REJECTING renegotiated session");
errno = ECONNABORTED;
return -1;
}
if (to == 0)
return ret;
for(;;) {
memset(&p, 0, sizeof(p));
BIO_get_fd(bio, &p.fd);
p.events = (cmd == BIO_CB_READ)? (POLLIN | POLLPRI): POLLOUT;
p_res = poll(&p, 1, to);
p_err = errno;
switch(p_res) {
case 1:
if(cmd == BIO_CB_READ) {
if((p.revents & POLLIN) || (p.revents & POLLPRI))
/* there is readable data */
return ret;
else {
#ifdef EBUG
logmsg(LOG_WARNING, "(%lx) CALLBACK read 0x%04x poll: %s",
pthread_self(), p.revents, strerror(p_err));
#endif
errno = EIO;
}
} else {
if(p.revents & POLLOUT)
/* data can be written */
return ret;
else {
#ifdef EBUG
logmsg(LOG_WARNING, "(%lx) CALLBACK write 0x%04x poll: %s",
pthread_self(), p.revents, strerror(p_err));
#endif
errno = ECONNRESET;
}
}
return -1;
case 0:
/* timeout - mark the BIO as unusable for the future */
bio_arg->timeout = err_to;
#ifdef EBUG
logmsg(LOG_WARNING, "(%lx) CALLBACK timeout poll after %d secs: %s",
pthread_self(), to / 1000, strerror(p_err));
#endif
errno = ETIMEDOUT;
return 0;
default:
/* error */
if(p_err != EINTR) {
#ifdef EBUG
logmsg(LOG_WARNING, "(%lx) CALLBACK bad %d poll: %s",
pthread_self(), p_res, strerror(p_err));
#endif
return -2;
#ifdef EBUG
} else
logmsg(LOG_WARNING, "(%lx) CALLBACK interrupted %d poll: %s",
pthread_self(), p_res, strerror(p_err));
#else
}
#endif
}
}
}
/*
* Check if the file underlying a BIO is readable
*/
static int
is_readable(BIO *const bio, const int to_wait)
{
struct pollfd p;
if(BIO_pending(bio) > 0)
return 1;
memset(&p, 0, sizeof(p));
BIO_get_fd(bio, &p.fd);
p.events = POLLIN | POLLPRI;
return (poll(&p, 1, to_wait * 1000) > 0);
}
static void
free_headers(char **headers)
{
int i;
for(i = 0; i < MAXHEADERS; i++)
if(headers[i])
free(headers[i]);
free(headers);
return;
}
static char **
get_headers(BIO *const in, BIO *const cl, const LISTENER *lstn)
{
char **headers, buf[MAXBUF];
int res, n, has_eol;
/* HTTP/1.1 allows leading CRLF */
memset(buf, 0, MAXBUF);
while((res = get_line(in, buf, MAXBUF)) == 0)
if(buf[0])
break;
if(res < 0) {
/* this is expected to occur only on client reads */
/* logmsg(LOG_NOTICE, "headers: bad starting read"); */
return NULL;
}
if((headers = (char **)calloc(MAXHEADERS, sizeof(char *))) == NULL) {
logmsg(LOG_WARNING, "(%lx) e500 headers: out of memory", pthread_self());
err_reply(cl, h500, lstn->err500);
return NULL;
}
if((headers[0] = (char *)malloc(MAXBUF)) == NULL) {
free_headers(headers);
logmsg(LOG_WARNING, "(%lx) e500 header: out of memory", pthread_self());
err_reply(cl, h500, lstn->err500);
return NULL;
}
memset(headers[0], 0, MAXBUF);
strncpy(headers[0], buf, MAXBUF - 1);
for(n = 1; n < MAXHEADERS; n++) {
if(get_line(in, buf, MAXBUF)) {
free_headers(headers);
/* this is not necessarily an error, EOF/timeout are possible
logmsg(LOG_WARNING, "(%lx) e500 can't read header", pthread_self());
err_reply(cl, h500, lstn->err500);
*/
return NULL;
}
if(!buf[0])
return headers;
if((headers[n] = (char *)malloc(MAXBUF)) == NULL) {
free_headers(headers);
logmsg(LOG_WARNING, "(%lx) e500 header: out of memory", pthread_self());
err_reply(cl, h500, lstn->err500);
return NULL;
}
memset(headers[n], 0, MAXBUF);
strncpy(headers[n], buf, MAXBUF - 1);
}
free_headers(headers);
logmsg(LOG_NOTICE, "(%lx) e500 too many headers", pthread_self());
err_reply(cl, h500, lstn->err500);
return NULL;
}
#define LOG_TIME_SIZE 32
/*
* Apache log-file-style time format
*/
static void
log_time(char *res)
{
time_t now;
struct tm *t_now, t_res;
now = time(NULL);
#ifdef HAVE_LOCALTIME_R
t_now = localtime_r(&now, &t_res);
#else
t_now = localtime(&now);
#endif
strftime(res, LOG_TIME_SIZE - 1, "%d/%b/%Y:%H:%M:%S %z", t_now);
return;
}
static double
cur_time(void)
{
#ifdef HAVE_GETTIMEOFDAY
struct timeval tv;
struct timezone tz;
int sv_errno;
sv_errno = errno;
gettimeofday(&tv, &tz);
errno = sv_errno;
return tv.tv_sec * 1000000.0 + tv.tv_usec;
#else
return time(NULL) * 1000000.0;
#endif
}
#define LOG_BYTES_SIZE 32
/*
* Apache log-file-style number format
*/
static void
log_bytes(char *res, const LONG cnt)
{
if(cnt > L0)
#ifdef HAVE_LONG_LONG_INT
snprintf(res, LOG_BYTES_SIZE - 1, "%lld", cnt);
#else
snprintf(res, LOG_BYTES_SIZE - 1, "%ld", cnt);
#endif
else
strcpy(res, "-");
return;
}
/* Cleanup code. This should really be in the pthread_cleanup_push, except for bugs in some implementations */
#define clean_all() { \
if(ssl != NULL) { BIO_ssl_shutdown(cl); } \
if(be != NULL) { BIO_flush(be); BIO_reset(be); BIO_free_all(be); be = NULL; } \
if(cl != NULL) { BIO_flush(cl); BIO_reset(cl); BIO_free_all(cl); cl = NULL; } \
if(x509 != NULL) { X509_free(x509); x509 = NULL; } \
if(ssl != NULL) { ERR_clear_error(); ERR_remove_state(0); } \
}
/*
* handle an HTTP request
*/
void
do_http(thr_arg *arg)
{
int cl_11, be_11, res, chunked, n, sock, no_cont, skip, conn_closed, force_10, sock_proto, is_rpc;
LISTENER *lstn;
SERVICE *svc;
BACKEND *backend, *cur_backend, *old_backend;
struct addrinfo from_host, z_addr;
struct sockaddr_storage from_host_addr;
BIO *cl, *be, *bb, *b64;
X509 *x509;
char request[MAXBUF], response[MAXBUF], buf[MAXBUF], url[MAXBUF], loc_path[MAXBUF], **headers,
headers_ok[MAXHEADERS], v_host[MAXBUF], referer[MAXBUF], u_agent[MAXBUF], u_name[MAXBUF],
caddr[MAXBUF], req_time[LOG_TIME_SIZE], s_res_bytes[LOG_BYTES_SIZE], *mh;
SSL *ssl, *be_ssl;
LONG cont, res_bytes;
regmatch_t matches[4];
struct linger l;
double start_req, end_req;
RENEG_STATE reneg_state;
BIO_ARG ba1, ba2;
reneg_state = RENEG_INIT;
ba1.reneg_state = &reneg_state;
ba2.reneg_state = &reneg_state;
ba1.timeout = 0;
ba2.timeout = 0;
from_host = ((thr_arg *)arg)->from_host;
memcpy(&from_host_addr, from_host.ai_addr, from_host.ai_addrlen);
from_host.ai_addr = (struct sockaddr *)&from_host_addr;
lstn = ((thr_arg *)arg)->lstn;
sock = ((thr_arg *)arg)->sock;
free(((thr_arg *)arg)->from_host.ai_addr);
free(arg);
if(lstn->allow_client_reneg)
reneg_state = RENEG_ALLOW;
n = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&n, sizeof(n));
l.l_onoff = 1;
l.l_linger = 10;
setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&l, sizeof(l));
#ifdef TCP_LINGER2
n = 5;
setsockopt(sock, SOL_TCP, TCP_LINGER2, (void *)&n, sizeof(n));
#endif
n = 1;
setsockopt(sock, SOL_TCP, TCP_NODELAY, (void *)&n, sizeof(n));
cl = NULL;
be = NULL;
ssl = NULL;
x509 = NULL;
if((cl = BIO_new_socket(sock, 1)) == NULL) {
logmsg(LOG_WARNING, "(%lx) BIO_new_socket failed", pthread_self());
shutdown(sock, 2);
close(sock);
return;
}
ba1.timeout = lstn->to;
BIO_set_callback_arg(cl, (char *)&ba1);
BIO_set_callback(cl, bio_callback);
if(lstn->ctx != NULL) {
if((ssl = SSL_new(lstn->ctx->ctx)) == NULL) {
logmsg(LOG_WARNING, "(%lx) SSL_new: failed", pthread_self());
BIO_reset(cl);
BIO_free_all(cl);
return;
}
SSL_set_app_data(ssl, &reneg_state);
SSL_set_bio(ssl, cl, cl);
if((bb = BIO_new(BIO_f_ssl())) == NULL) {
logmsg(LOG_WARNING, "(%lx) BIO_new(Bio_f_ssl()) failed", pthread_self());
BIO_reset(cl);
BIO_free_all(cl);
return;
}
BIO_set_ssl(bb, ssl, BIO_CLOSE);
BIO_set_ssl_mode(bb, 0);
cl = bb;
if(BIO_do_handshake(cl) <= 0) {
/* no need to log every client without a certificate...
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "BIO_do_handshake with %s failed: %s", caddr,
ERR_error_string(ERR_get_error(), NULL));
x509 = NULL;
*/
BIO_reset(cl);
BIO_free_all(cl);
return;
} else {
if((x509 = SSL_get_peer_certificate(ssl)) != NULL && lstn->clnt_check < 3
&& SSL_get_verify_result(ssl) != X509_V_OK) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "Bad certificate from %s", caddr);
X509_free(x509);
BIO_reset(cl);
BIO_free_all(cl);
return;
}
}
} else {
x509 = NULL;
}
cur_backend = NULL;
if((bb = BIO_new(BIO_f_buffer())) == NULL) {
logmsg(LOG_WARNING, "(%lx) BIO_new(buffer) failed", pthread_self());
if(x509 != NULL)
X509_free(x509);
BIO_reset(cl);
BIO_free_all(cl);
return;
}
BIO_set_close(cl, BIO_CLOSE);
BIO_set_buffer_size(cl, MAXBUF);
cl = BIO_push(bb, cl);
for(cl_11 = be_11 = 0;;) {
res_bytes = L0;
is_rpc = -1;
v_host[0] = referer[0] = u_agent[0] = u_name[0] = '\0';
conn_closed = 0;
for(n = 0; n < MAXHEADERS; n++)
headers_ok[n] = 1;
if((headers = get_headers(cl, cl, lstn)) == NULL) {
if(!cl_11) {
if(errno) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) error read from %s: %s", pthread_self(), caddr, strerror(errno));
/* err_reply(cl, h500, lstn->err500); */
}
}
clean_all();
return;
}
memset(req_time, 0, LOG_TIME_SIZE);
start_req = cur_time();
log_time(req_time);
/* check for correct request */
strncpy(request, headers[0], MAXBUF);
if(!regexec(&lstn->verb, request, 3, matches, 0)) {
no_cont = !strncasecmp(request + matches[1].rm_so, "HEAD", matches[1].rm_eo - matches[1].rm_so);
if(!strncasecmp(request + matches[1].rm_so, "RPC_IN_DATA", matches[1].rm_eo - matches[1].rm_so))
is_rpc = 1;
else if(!strncasecmp(request + matches[1].rm_so, "RPC_OUT_DATA", matches[1].rm_eo - matches[1].rm_so))
is_rpc = 0;
} else {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_WARNING, "(%lx) e501 bad request \"%s\" from %s", pthread_self(), request, caddr);
err_reply(cl, h501, lstn->err501);
free_headers(headers);
clean_all();
return;
}
cl_11 = (request[strlen(request) - 1] == '1');
n = cpURL(url, request + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
if(n != strlen(url)) {
/* the URL probably contained a %00 aka NULL - which we don't allow */
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e501 URL \"%s\" (contains NULL) from %s", pthread_self(), url, caddr);
err_reply(cl, h501, lstn->err501);
free_headers(headers);
clean_all();
return;
}
if(lstn->has_pat && regexec(&lstn->url_pat, url, 0, NULL, 0)) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e501 bad URL \"%s\" from %s", pthread_self(), url, caddr);
err_reply(cl, h501, lstn->err501);
free_headers(headers);
clean_all();
return;
}
/* check other headers */
for(chunked = 0, cont = L_1, n = 1; n < MAXHEADERS && headers[n]; n++) {
/* no overflow - see check_header for details */
switch(check_header(headers[n], buf)) {
case HEADER_HOST:
strcpy(v_host, buf);
break;
case HEADER_REFERER:
strcpy(referer, buf);
break;
case HEADER_USER_AGENT:
strcpy(u_agent, buf);
break;
case HEADER_CONNECTION:
if(!strcasecmp("close", buf))
conn_closed = 1;
break;
case HEADER_TRANSFER_ENCODING:
if(!strcasecmp("chunked", buf))
chunked = 1;
else {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e400 multiple Transfer-encoding \"%s\" from %s", pthread_self(), url, caddr);
err_reply(cl, h400, "Bad request: multiple Transfer-encoding values");
free_headers(headers);
clean_all();
return;
}
break;
case HEADER_CONTENT_LENGTH:
if(cont != L_1 || strchr(buf, ',')) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e400 multiple Content-length \"%s\" from %s", pthread_self(), url, caddr);
err_reply(cl, h400, "Bad request: multiple Content-length values");
free_headers(headers);
clean_all();
return;
}
for(mh = buf; *mh; mh++)
if(!isdigit(*mh)) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e400 Content-length bad value \"%s\" from %s", pthread_self(), url, caddr);
err_reply(cl, h400, "Bad request: Content-length bad value");
free_headers(headers);
clean_all();
return;
}
if((cont = ATOL(buf)) < 0L)
headers_ok[n] = 0;
if(is_rpc == 1 && (cont < 0x20000L || cont > 0x80000000L))
is_rpc = -1;
break;
case HEADER_EXPECT:
/*
* we do NOT support the "Expect: 100-continue" headers
* support may involve severe performance penalties (non-responding back-end, etc)
* as a stop-gap measure we just skip these headers
*/
if(!strcasecmp("100-continue", buf))
headers_ok[n] = 0;
break;
case HEADER_ILLEGAL:
if(lstn->log_level > 0) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) bad header from %s (%s)", pthread_self(), caddr, headers[n]);
}
headers_ok[n] = 0;
break;
}
if(headers_ok[n] && lstn->head_off) {
/* maybe header to be removed */
MATCHER *m;
for(m = lstn->head_off; m; m = m->next)
if(!(headers_ok[n] = regexec(&m->pat, headers[n], 0, NULL, 0)))
break;
}
/* get User name */
if(!regexec(&AUTHORIZATION, headers[n], 2, matches, 0)) {
int inlen;
if((bb = BIO_new(BIO_s_mem())) == NULL) {
logmsg(LOG_WARNING, "(%lx) Can't alloc BIO_s_mem", pthread_self());
continue;
}
if((b64 = BIO_new(BIO_f_base64())) == NULL) {
logmsg(LOG_WARNING, "(%lx) Can't alloc BIO_f_base64", pthread_self());
BIO_free(bb);
continue;
}
b64 = BIO_push(b64, bb);
BIO_write(bb, headers[n] + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
BIO_write(bb, "\n", 1);
if((inlen = BIO_read(b64, buf, MAXBUF - 1)) <= 0) {
logmsg(LOG_WARNING, "(%lx) Can't read BIO_f_base64", pthread_self());
BIO_free_all(b64);
continue;
}
BIO_free_all(b64);
if((mh = strchr(buf, ':')) == NULL) {
logmsg(LOG_WARNING, "(%lx) Unknown authentication", pthread_self());
continue;
}
*mh = '\0';
strcpy(u_name, buf);
}
}
/* check for possible request smuggling attempt */
if(chunked != 0 && cont != L_1) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e501 Transfer-encoding and Content-length \"%s\" from %s", pthread_self(), url, caddr);
err_reply(cl, h400, "Bad request: Transfer-encoding and Content-length headers present");
free_headers(headers);
clean_all();
return;
}
/* possibly limited request size */
if(lstn->max_req > L0 && cont > L0 && cont > lstn->max_req && is_rpc != 1) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e501 request too large (%ld) from %s", pthread_self(), cont, caddr);
err_reply(cl, h501, lstn->err501);
free_headers(headers);
clean_all();
return;
}
if(be != NULL) {
if(is_readable(be, 0)) {
/* The only way it's readable is if it's at EOF, so close it! */
BIO_reset(be);
BIO_free_all(be);
be = NULL;
}
}
/* check that the requested URL still fits the old back-end (if any) */
if((svc = get_service(lstn, url, &headers[1])) == NULL) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e503 no service \"%s\" from %s %s", pthread_self(), request, caddr, v_host[0]? v_host: "-");
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
if((backend = get_backend(svc, &from_host, url, &headers[1])) == NULL) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e503 no back-end \"%s\" from %s %s", pthread_self(), request, caddr, v_host[0]? v_host: "-");
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
if(be != NULL && backend != cur_backend) {
BIO_reset(be);
BIO_free_all(be);
be = NULL;
}
while(be == NULL && backend->be_type == 0) {
switch(backend->addr.ai_family) {
case AF_INET:
sock_proto = PF_INET;
break;
case AF_INET6:
sock_proto = PF_INET6;
break;
case AF_UNIX:
sock_proto = PF_UNIX;
break;
default:
logmsg(LOG_WARNING, "(%lx) e503 backend: unknown family %d", pthread_self(), backend->addr.ai_family);
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
if((sock = socket(sock_proto, SOCK_STREAM, 0)) < 0) {
str_be(buf, MAXBUF - 1, backend);
logmsg(LOG_WARNING, "(%lx) e503 backend %s socket create: %s", pthread_self(), buf, strerror(errno));
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
if(connect_nb(sock, &backend->addr, backend->conn_to) < 0) {
str_be(buf, MAXBUF - 1, backend);
logmsg(LOG_WARNING, "(%lx) backend %s connect: %s", pthread_self(), buf, strerror(errno));
shutdown(sock, 2);
close(sock);
/*
* kill the back-end only if no HAport is defined for it
* otherwise allow the HAport mechanism to do its job
*/
memset(&z_addr, 0, sizeof(z_addr));
if(memcmp(&(backend->ha_addr), &(z_addr), sizeof(z_addr)) == 0)
kill_be(svc, backend, BE_KILL);
/*
* ...but make sure we don't get into a loop with the same back-end
*/
old_backend = backend;
if((backend = get_backend(svc, &from_host, url, &headers[1])) == NULL || backend == old_backend) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e503 no back-end \"%s\" from %s", pthread_self(), request, caddr);
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
continue;
}
if(sock_proto == PF_INET || sock_proto == PF_INET6) {
n = 1;
setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, (void *)&n, sizeof(n));
l.l_onoff = 1;
l.l_linger = 10;
setsockopt(sock, SOL_SOCKET, SO_LINGER, (void *)&l, sizeof(l));
#ifdef TCP_LINGER2
n = 5;
setsockopt(sock, SOL_TCP, TCP_LINGER2, (void *)&n, sizeof(n));
#endif
n = 1;
setsockopt(sock, SOL_TCP, TCP_NODELAY, (void *)&n, sizeof(n));
}
if((be = BIO_new_socket(sock, 1)) == NULL) {
logmsg(LOG_WARNING, "(%lx) e503 BIO_new_socket server failed", pthread_self());
shutdown(sock, 2);
close(sock);
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
BIO_set_close(be, BIO_CLOSE);
if(backend->to > 0) {
ba2.timeout = backend->to;
BIO_set_callback_arg(be, (char *)&ba2);
BIO_set_callback(be, bio_callback);
}
if(backend->ctx != NULL) {
if((be_ssl = SSL_new(backend->ctx)) == NULL) {
logmsg(LOG_WARNING, "(%lx) be SSL_new: failed", pthread_self());
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
SSL_set_bio(be_ssl, be, be);
if((bb = BIO_new(BIO_f_ssl())) == NULL) {
logmsg(LOG_WARNING, "(%lx) BIO_new(Bio_f_ssl()) failed", pthread_self());
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
BIO_set_ssl(bb, be_ssl, BIO_CLOSE);
BIO_set_ssl_mode(bb, 1);
be = bb;
if(BIO_do_handshake(be) <= 0) {
str_be(buf, MAXBUF - 1, backend);
logmsg(LOG_NOTICE, "BIO_do_handshake with %s failed: %s", buf,
ERR_error_string(ERR_get_error(), NULL));
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
}
if((bb = BIO_new(BIO_f_buffer())) == NULL) {
logmsg(LOG_WARNING, "(%lx) e503 BIO_new(buffer) server failed", pthread_self());
err_reply(cl, h503, lstn->err503);
free_headers(headers);
clean_all();
return;
}
BIO_set_buffer_size(bb, MAXBUF);
BIO_set_close(bb, BIO_CLOSE);
be = BIO_push(bb, be);
}
cur_backend = backend;
/* if we have anything but a BACK_END we close the channel */
if(be != NULL && cur_backend->be_type) {
BIO_reset(be);
BIO_free_all(be);
be = NULL;
}
/* send the request */
if(cur_backend->be_type == 0) {
for(n = 0; n < MAXHEADERS && headers[n]; n++) {
if(!headers_ok[n])
continue;
/* this is the earliest we can check for Destination - we had no back-end before */
if(lstn->rewr_dest && check_header(headers[n], buf) == HEADER_DESTINATION) {
if(regexec(&LOCATION, buf, 4, matches, 0)) {
logmsg(LOG_NOTICE, "(%lx) Can't parse Destination %s", pthread_self(), buf);
break;
}
str_be(caddr, MAXBUF - 1, cur_backend);
strcpy(loc_path, buf + matches[3].rm_so);
snprintf(buf, MAXBUF, "Destination: http://%s%s", caddr, loc_path);
free(headers[n]);
if((headers[n] = strdup(buf)) == NULL) {
logmsg(LOG_WARNING, "(%lx) rewrite Destination - out of memory: %s",
pthread_self(), strerror(errno));
free_headers(headers);
clean_all();
return;
}
}
if(BIO_printf(be, "%s\r\n", headers[n]) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write to %s/%s: %s (%.3f sec)",
pthread_self(), buf, request, strerror(errno),
(end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
free_headers(headers);
clean_all();
return;
}
}
/* add header if required */
if(lstn->add_head != NULL)
if(BIO_printf(be, "%s\r\n", lstn->add_head) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write AddHeader to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
free_headers(headers);
clean_all();
return;
}
}
free_headers(headers);
/* if SSL put additional headers for client certificate */
if(cur_backend->be_type == 0 && ssl != NULL) {
const SSL_CIPHER *cipher;
if((cipher = SSL_get_current_cipher(ssl)) != NULL) {
SSL_CIPHER_description(cipher, buf, MAXBUF - 1);
strip_eol(buf);
if(BIO_printf(be, "X-SSL-cipher: %s/%s\r\n", SSL_get_version(ssl), buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-cipher to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
clean_all();
return;
}
}
if(lstn->clnt_check > 0 && x509 != NULL && (bb = BIO_new(BIO_s_mem())) != NULL) {
X509_NAME_print_ex(bb, X509_get_subject_name(x509), 8, XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB);
get_line(bb, buf, MAXBUF);
if(BIO_printf(be, "X-SSL-Subject: %s\r\n", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-Subject to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
X509_NAME_print_ex(bb, X509_get_issuer_name(x509), 8, XN_FLAG_ONELINE & ~ASN1_STRFLGS_ESC_MSB);
get_line(bb, buf, MAXBUF);
if(BIO_printf(be, "X-SSL-Issuer: %s\r\n", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-Issuer to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
ASN1_TIME_print(bb, X509_get_notBefore(x509));
get_line(bb, buf, MAXBUF);
if(BIO_printf(be, "X-SSL-notBefore: %s\r\n", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-notBefore to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
ASN1_TIME_print(bb, X509_get_notAfter(x509));
get_line(bb, buf, MAXBUF);
if(BIO_printf(be, "X-SSL-notAfter: %s\r\n", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-notAfter to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
if(BIO_printf(be, "X-SSL-serial: %ld\r\n", ASN1_INTEGER_get(X509_get_serialNumber(x509))) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-serial to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
PEM_write_bio_X509(bb, x509);
get_line(bb, buf, MAXBUF);
if(BIO_printf(be, "X-SSL-certificate: %s", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-certificate to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
while(get_line(bb, buf, MAXBUF) == 0) {
if(BIO_printf(be, "%s", buf) <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-certificate to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
}
if(BIO_printf(be, "\r\n") <= 0) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
logmsg(LOG_WARNING, "(%lx) e500 error write X-SSL-certificate to %s: %s (%.3f sec)",
pthread_self(), buf, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
BIO_free_all(bb);
clean_all();
return;
}
BIO_free_all(bb);
}
}
/* put additional client IP header */
if(cur_backend->be_type == 0) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
BIO_printf(be, "X-Forwarded-For: %s\r\n", caddr);
/* final CRLF */
BIO_puts(be, "\r\n");
}
if(cl_11 && chunked) {
/* had Transfer-encoding: chunked so read/write all the chunks (HTTP/1.1 only) */
if(copy_chunks(cl, be, NULL, cur_backend->be_type, lstn->max_req)) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e500 for %s copy_chunks to %s/%s (%.3f sec)",
pthread_self(), caddr, buf, request, (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
clean_all();
return;
}
} else if(cont > L0 && is_rpc != 1) {
/* had Content-length, so do raw reads/writes for the length */
if(copy_bin(cl, be, cont, NULL, cur_backend->be_type)) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e500 for %s error copy client cont to %s/%s: %s (%.3f sec)",
pthread_self(), caddr, buf, request, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
clean_all();
return;
}
} else if(cont > 0L && is_readable(cl, lstn->to)) {
char one;
BIO *cl_unbuf;
/*
* special mode for RPC_IN_DATA - content until EOF
* force HTTP/1.0 - client closes connection when done.
*/
cl_11 = be_11 = 0;
/*
* first read whatever is already in the input buffer
*/
while(BIO_pending(cl)) {
if(BIO_read(cl, &one, 1) != 1) {
logmsg(LOG_NOTICE, "(%lx) error read request pending: %s",
pthread_self(), strerror(errno));
clean_all();
pthread_exit(NULL);
}
if (++res_bytes > cont) {
logmsg(LOG_NOTICE, "(%lx) error read request pending: max. RPC length exceeded",
pthread_self());
clean_all();
pthread_exit(NULL);
}
if(BIO_write(be, &one, 1) != 1) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error write request pending: %s",
pthread_self(), strerror(errno));
clean_all();
pthread_exit(NULL);
}
}
BIO_flush(be);
/*
* find the socket BIO in the chain
*/
if ((cl_unbuf = BIO_find_type(cl, lstn->ctx? BIO_TYPE_SSL : BIO_TYPE_SOCKET)) == NULL) {
logmsg(LOG_WARNING, "(%lx) error get unbuffered: %s", pthread_self(), strerror(errno));
clean_all();
pthread_exit(NULL);
}
/*
* copy till EOF
*/
while((res = BIO_read(cl_unbuf, buf, MAXBUF)) > 0) {
if((res_bytes += res) > cont) {
logmsg(LOG_NOTICE, "(%lx) error copy request body: max. RPC length exceeded",
pthread_self());
clean_all();
pthread_exit(NULL);
}
if(BIO_write(be, buf, res) != res) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error copy request body: %s",
pthread_self(), strerror(errno));
clean_all();
pthread_exit(NULL);
} else {
BIO_flush(be);
}
}
}
/* flush to the back-end */
if(cur_backend->be_type == 0 && BIO_flush(be) != 1) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e500 for %s error flush to %s/%s: %s (%.3f sec)",
pthread_self(), caddr, buf, request, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
clean_all();
return;
}
/*
* check on no_https_11:
* - if 0 ignore
* - if 1 and SSL force HTTP/1.0
* - if 2 and SSL and MSIE force HTTP/1.0
*/
switch(lstn->noHTTPS11) {
case 1:
force_10 = (ssl != NULL);
break;
case 2:
force_10 = (ssl != NULL && strstr(u_agent, "MSIE") != NULL);
break;
default:
force_10 = 0;
break;
}
/* if we have a redirector */
if(cur_backend->be_type) {
memset(buf, 0, sizeof(buf));
if(!cur_backend->redir_req)
snprintf(buf, sizeof(buf) - 1, "%s%s", cur_backend->url, url);
else
strncpy(buf, cur_backend->url, sizeof(buf) - 1);
redirect_reply(cl, buf, cur_backend->be_type);
addr2str(caddr, MAXBUF - 1, &from_host, 1);
switch(lstn->log_level) {
case 0:
break;
case 1:
case 2:
logmsg(LOG_INFO, "%s %s - REDIRECT %s", caddr, request, buf);
break;
case 3:
if(v_host[0])
logmsg(LOG_INFO, "%s %s - %s [%s] \"%s\" %d 0 \"%s\" \"%s\"", v_host, caddr,
u_name[0]? u_name: "-", req_time, request, cur_backend->be_type, referer, u_agent);
else
logmsg(LOG_INFO, "%s - %s [%s] \"%s\" %d 0 \"%s\" \"%s\"", caddr,
u_name[0]? u_name: "-", req_time, request, cur_backend->be_type, referer, u_agent);
break;
case 4:
case 5:
logmsg(LOG_INFO, "%s - %s [%s] \"%s\" %d 0 \"%s\" \"%s\"", caddr,
u_name[0]? u_name: "-", req_time, request, cur_backend->be_type, referer, u_agent);
break;
}
if(!cl_11 || conn_closed || force_10)
break;
continue;
} else if(is_rpc == 1) {
/* log RPC_IN_DATA */
end_req = cur_time();
memset(s_res_bytes, 0, LOG_BYTES_SIZE);
/* actual request length */
log_bytes(s_res_bytes, res_bytes);
addr2str(caddr, MAXBUF - 1, &from_host, 1);
str_be(buf, MAXBUF - 1, cur_backend);
switch(lstn->log_level) {
case 0:
break;
case 1:
logmsg(LOG_INFO, "%s %s - -", caddr, request);
break;
case 2:
if(v_host[0])
logmsg(LOG_INFO, "%s %s - - (%s/%s -> %s) %.3f sec",
caddr, request, v_host, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
else
logmsg(LOG_INFO, "%s %s - - (%s -> %s) %.3f sec",
caddr, request, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
break;
case 3:
logmsg(LOG_INFO, "%s %s - %s [%s] \"%s\" 000 %s \"%s\" \"%s\"",
v_host[0]? v_host: "-",
caddr, u_name[0]? u_name: "-", req_time, request,
s_res_bytes, referer, u_agent);
break;
case 4:
logmsg(LOG_INFO, "%s - %s [%s] \"%s\" 000 %s \"%s\" \"%s\"",
caddr, u_name[0]? u_name: "-", req_time, request,
s_res_bytes, referer, u_agent);
break;
case 5:
logmsg(LOG_INFO, "%s %s - %s [%s] \"%s\" 000 %s \"%s\" \"%s\" (%s -> %s) %.3f sec",
v_host[0]? v_host: "-",
caddr, u_name[0]? u_name: "-", req_time, request,
s_res_bytes, referer, u_agent, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
break;
}
/* no response expected - bail out */
break;
}
/* get the response */
for(skip = 1; skip;) {
if((headers = get_headers(be, cl, lstn)) == NULL) {
str_be(buf, MAXBUF - 1, cur_backend);
end_req = cur_time();
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) e500 for %s response error read from %s/%s: %s (%.3f secs)",
pthread_self(), caddr, buf, request, strerror(errno), (end_req - start_req) / 1000000.0);
err_reply(cl, h500, lstn->err500);
clean_all();
return;
}
strncpy(response, headers[0], MAXBUF);
be_11 = (response[7] == '1');
/* responses with code 100 are never passed back to the client */
skip = !regexec(&RESP_SKIP, response, 0, NULL, 0);
/* some response codes (1xx, 204, 304) have no content */
if(!no_cont && !regexec(&RESP_IGN, response, 0, NULL, 0))
no_cont = 1;
for(chunked = 0, cont = -1L, n = 1; n < MAXHEADERS && headers[n]; n++) {
switch(check_header(headers[n], buf)) {
case HEADER_CONNECTION:
if(!strcasecmp("close", buf))
conn_closed = 1;
break;
case HEADER_TRANSFER_ENCODING:
if(!strcasecmp("chunked", buf)) {
chunked = 1;
no_cont = 0;
}
break;
case HEADER_CONTENT_LENGTH:
cont = ATOL(buf);
/* treat RPC_OUT_DATA like reply without content-length */
if(is_rpc == 0) {
if(cont >= 0x20000L && cont <= 0x80000000L)
cont = -1L;
else
is_rpc = -1;
}
break;
case HEADER_LOCATION:
if(v_host[0] && need_rewrite(lstn->rewr_loc, buf, loc_path, v_host, lstn, cur_backend)) {
snprintf(buf, MAXBUF, "Location: %s://%s/%s",
(ssl == NULL? "http": "https"), v_host, loc_path);
free(headers[n]);
if((headers[n] = strdup(buf)) == NULL) {
logmsg(LOG_WARNING, "(%lx) rewrite Location - out of memory: %s",
pthread_self(), strerror(errno));
free_headers(headers);
clean_all();
return;
}
}
break;
case HEADER_CONTLOCATION:
if(v_host[0] && need_rewrite(lstn->rewr_loc, buf, loc_path, v_host, lstn, cur_backend)) {
snprintf(buf, MAXBUF, "Content-location: %s://%s/%s",
(ssl == NULL? "http": "https"), v_host, loc_path);
free(headers[n]);
if((headers[n] = strdup(buf)) == NULL) {
logmsg(LOG_WARNING, "(%lx) rewrite Content-location - out of memory: %s",
pthread_self(), strerror(errno));
free_headers(headers);
clean_all();
return;
}
}
break;
}
}
/* possibly record session information (only for cookies/header) */
upd_session(svc, &headers[1], cur_backend);
/* send the response */
if(!skip)
for(n = 0; n < MAXHEADERS && headers[n]; n++) {
if(BIO_printf(cl, "%s\r\n", headers[n]) <= 0) {
if(errno) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) error write to %s: %s", pthread_self(), caddr, strerror(errno));
}
free_headers(headers);
clean_all();
return;
}
}
free_headers(headers);
/* final CRLF */
if(!skip)
BIO_puts(cl, "\r\n");
if(BIO_flush(cl) != 1) {
if(errno) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) error flush headers to %s: %s", pthread_self(), caddr, strerror(errno));
}
clean_all();
return;
}
if(!no_cont) {
/* ignore this if request was HEAD or similar */
if(be_11 && chunked) {
/* had Transfer-encoding: chunked so read/write all the chunks (HTTP/1.1 only) */
if(copy_chunks(be, cl, &res_bytes, skip, L0)) {
/* copy_chunks() has its own error messages */
clean_all();
return;
}
} else if(cont >= L0) {
/* may have had Content-length, so do raw reads/writes for the length */
if(copy_bin(be, cl, cont, &res_bytes, skip)) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error copy server cont: %s", pthread_self(), strerror(errno));
clean_all();
return;
}
} else if(!skip) {
if(is_readable(be, cur_backend->to)) {
char one;
BIO *be_unbuf;
/*
* old-style response - content until EOF
* also implies the client may not use HTTP/1.1
*/
cl_11 = be_11 = 0;
/*
* first read whatever is already in the input buffer
*/
while(BIO_pending(be)) {
if(BIO_read(be, &one, 1) != 1) {
logmsg(LOG_NOTICE, "(%lx) error read response pending: %s",
pthread_self(), strerror(errno));
clean_all();
return;
}
if(BIO_write(cl, &one, 1) != 1) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error write response pending: %s",
pthread_self(), strerror(errno));
clean_all();
return;
}
res_bytes++;
}
BIO_flush(cl);
/*
* find the socket BIO in the chain
*/
if((be_unbuf = BIO_find_type(be, cur_backend->ctx? BIO_TYPE_SSL : BIO_TYPE_SOCKET)) == NULL) {
logmsg(LOG_WARNING, "(%lx) error get unbuffered: %s", pthread_self(), strerror(errno));
clean_all();
return;
}
/*
* copy till EOF
*/
while((res = BIO_read(be_unbuf, buf, MAXBUF)) > 0) {
if(BIO_write(cl, buf, res) != res) {
if(errno)
logmsg(LOG_NOTICE, "(%lx) error copy response body: %s",
pthread_self(), strerror(errno));
clean_all();
return;
} else {
res_bytes += res;
BIO_flush(cl);
}
}
}
}
if(BIO_flush(cl) != 1) {
/* client closes RPC_OUT_DATA connection - no error */
if(is_rpc == 0 && res_bytes > 0L)
break;
if(errno) {
addr2str(caddr, MAXBUF - 1, &from_host, 1);
logmsg(LOG_NOTICE, "(%lx) error final flush to %s: %s", pthread_self(), caddr, strerror(errno));
}
clean_all();
return;
}
}
}
end_req = cur_time();
/* log what happened */
memset(s_res_bytes, 0, LOG_BYTES_SIZE);
log_bytes(s_res_bytes, res_bytes);
addr2str(caddr, MAXBUF - 1, &from_host, 1);
if(anonymise) {
char *last;
if((last = strrchr(caddr, '.')) != NULL || (last = strrchr(caddr, ':')) != NULL)
strcpy(++last, "0");
}
str_be(buf, MAXBUF - 1, cur_backend);
switch(lstn->log_level) {
case 0:
break;
case 1:
logmsg(LOG_INFO, "%s %s - %s", caddr, request, response);
break;
case 2:
if(v_host[0])
logmsg(LOG_INFO, "%s %s - %s (%s/%s -> %s) %.3f sec",
caddr, request, response, v_host, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
else
logmsg(LOG_INFO, "%s %s - %s (%s -> %s) %.3f sec",
caddr, request, response, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
break;
case 3:
logmsg(LOG_INFO, "%s %s - %s [%s] \"%s\" %c%c%c %s \"%s\" \"%s\"",
v_host[0]? v_host: "-",
caddr, u_name[0]? u_name: "-", req_time, request, response[9],
response[10], response[11], s_res_bytes, referer, u_agent);
break;
case 4:
logmsg(LOG_INFO, "%s - %s [%s] \"%s\" %c%c%c %s \"%s\" \"%s\"",
caddr, u_name[0]? u_name: "-", req_time, request, response[9], response[10],
response[11], s_res_bytes, referer, u_agent);
break;
case 5:
logmsg(LOG_INFO, "%s %s - %s [%s] \"%s\" %c%c%c %s \"%s\" \"%s\" (%s -> %s) %.3f sec",
v_host[0]? v_host: "-",
caddr, u_name[0]? u_name: "-", req_time, request, response[9], response[10],
response[11], s_res_bytes, referer, u_agent, svc->name[0]? svc->name: "-", buf,
(end_req - start_req) / 1000000.0);
break;
}
if(!be_11) {
BIO_reset(be);
BIO_free_all(be);
be = NULL;
}
/*
* Stop processing if:
* - client is not HTTP/1.1
* or
* - we had a "Connection: closed" header
* or
* - this is an SSL connection and we had a NoHTTPS11 directive
*/
if(!cl_11 || conn_closed || force_10)
break;
}
/*
* This may help with some versions of IE with a broken channel shutdown
*/
if(ssl != NULL)
SSL_set_shutdown(ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN);
clean_all();
return;
}
void *
thr_http(void *dummy)
{
thr_arg *arg;
for(;;) {
while((arg = get_thr_arg()) == NULL)
logmsg(LOG_NOTICE, "NULL get_thr_arg");
do_http(arg);
}
}
Pound-2.8/z2_2_6_1.py 0000755 0001750 0001750 00000102337 13275266545 013313 0 ustar roseg roseg ##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""Zope 2 ZServer start-up file
Usage: %(program)s [options] [environment settings]
Options:
-h
Output this text.
-z path
The location of the Zope installation.
The default is the location of this script, %(here)s.
-Z 0 or 1
UNIX only! This option is ignored on Windows.
This option controls whether a management process will be created
that restarts Zope after a shutdown or crash.
If the argument to -Z is non-null (e.g. "-Z1" or "-Zyes"), a
management process will be used. If the argument to -Z is "-", or
"0", (e.g. "-Z-" or "-Z0"), a management process will not be used.
On UNIX, the default behavior is to create a separate management
process (e.g. -Z1) if the -Z option is not specified.
(Note: the -Z option in Zopes before Zope 2.6 used to be used to specify
a pidfile name for the management process. This pidfile no longer
exists).
-t n
The number of threads to use, if ZODB3 is used. The default is
%(NUMBER_OF_THREADS)s.
-i n
Set the interpreter check interval. This integer value
determines how often the interpreter checks for periodic things
such as thread switches and signal handlers. The Zope default
is 500, but you may want to experiment with other values that
may increase performance in your particular environment.
-D
Run in Zope debug mode. This causes the Zope process not to
detach from the controlling terminal, and is equivalent to
supplying the environment variable setting Z_DEBUG_MODE=1
-a ipaddress
The IP address to listen on. If this is an empty string
(e.g. -a ''), then all addresses on the machine are used. The
default is %(IP_ADDRESS)s.
-d ipaddress
IP address of your DNS server. If this is an empty string
(e.g. -d ''), then IP addresses will not be logged. If you have
DNS service on your local machine then you can set this to
127.0.0.1. The default is: %(DNS_IP)s.
-u username or uid number
The username to run ZServer as. You may want to run ZServer as
a dedicated user. This only works under Unix, and if ZServer
is started as root, and is required in that case.
-P [ipaddress:]number
Set the web, ftp and monitor port numbers simultaneously
as offsets from the number. The web port number will be number+80.
The FTP port number will be number+21. The monitor port number will
be number+99.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -P options can be provided to run multiple sets of servers.
-w port
The Web server (HTTP) port. This defaults to %(HTTP_PORT)s. The
standard port for HTTP services is 80. If this is a dash
(e.g. -w -), then HTTP is disabled.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -w options can be provided to run multiple servers.
-y port
The Web secure server (HTTPS) port. This defaults to %(HTTPS_PORT)s.
The standard port for HTTPS services is 443. If this is a dash
(e.g. -y -), then HTTPS is disabled.
The number can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -w options can be provided to run multiple servers.
-W port
The "WebDAV source" port. If this is a dash (e.g. -w -), then
"WebDAV source" is disabled. The default is disabled. Note that
this feature is a workaround for the lack of "source-link" support
in standard WebDAV clients.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -W options can be provided to run multiple servers.
-C
--force-http-connection-close
If present, this option causes Zope to close all HTTP connections,
regardless of the 'Connection:' header (or lack of one) sent by
the client.
-f port
The FTP port. If this is a dash (e.g. -f -), then FTP
is disabled. The standard port for FTP services is 21. The
default is %(FTP_PORT)s.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -f options can be provided to run multiple servers.
-p path
Path to the PCGI resource file. The default value is
%(PCGI_FILE)s, relative to the Zope location. If this is a dash
(-p -) or the file does not exist, then PCGI is disabled.
-F path_or_port
Either a port number (for inet sockets) or a path name (for unix
domain sockets) for the FastCGI Server. If the flag and value are
not specified then the FastCGI Server is disabled.
-m port
The secure monitor server port. If this is a dash
(-m -), then the monitor server is disabled. The monitor server
allows interactive Python style access to a running ZServer. To
access the server see medusa/monitor_client.py or
medusa/monitor_client_win32.py. The monitor server password is the
same as the Zope emergency user password set in the 'access'
file. The default is to not start up a monitor server.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple -m options can be provided to run multiple servers.
--icp port
The ICP port. ICP can be used to distribute load between back-end
zope servers, if you are using an ICP-aware front-end proxy such
as Squid.
The port can be preeceeded by an ip address follwed by a colon
to specify an address to listen on. This allows different servers
to listen on different addresses.
Multiple --icp options can be provided to run multiple servers.
-l path
Path to the ZServer log file. If this is a relative path then the
log file will be written to the 'var' directory. The default is
%(LOG_FILE)s.
-r
Run ZServer is read-only mode. ZServer won't write anything to disk.
No log files, no pid files, nothing. This means that you can't do a
lot of stuff like use PCGI, and zdaemon. ZServer will log hits to
STDOUT and zLOG will log to STDERR.
-L
Enable locale (internationalization) support. The value passed for
this option should be the name of the locale to be used (see your
operating system documentation for locale information specific to
your system). If an empty string is passed for this option (-L ''),
Zope will set the locale to the user's default setting (typically
specified in the $LANG environment variable). If your Python
installation does not support the locale module, the requested
locale is not supported by your system or an empty string was
passed but no default locale can be found, an error will be raised
and Zope will not start.
-X
Disable servers. This might be used to effectively disable all
default server settings or previous server settings in the option
list before providing new settings. For example to provide just a
web server:
%(program)s -X -w80
-M file
Save detailed logging information to the given file.
This log includes separate entries for:
- The start of a request,
- The start of processing the request in an application thread,
- The start of response output, and
- The end of the request.
Environment settings are of the form: NAME=VALUE.
Note: you *must* use Python 2.1 or later!
"""
# This is required path hackery for the win32 binary distribution
# that ensures that the bundled python libraries are used. In a
# win32 binary distribution, the installer will have replaced the
# marker string with the actual software home. If that has not
# happened, then the path munging code is skipped.
swhome=r'INSERT_SOFTWARE_HOME'
if swhome != 'INSERT_SOFTWARE_HOME':
import sys
sys.path.insert(0, '%s/lib/python' % swhome)
sys.path.insert(1, '%s/bin/lib' % swhome)
sys.path.insert(2, '%s/bin/lib/plat-win' % swhome)
sys.path.insert(3, '%s/bin/lib/win32' % swhome)
sys.path.insert(4, '%s/bin/lib/win32/lib' % swhome)
sys.path.insert(5, '%s' % swhome)
import os, sys, getopt, codecs, string
import socket
from types import StringType, IntType
# workaround to allow unicode encoding conversions in DTML
dummy = codecs.lookup('iso-8859-1')
sys.setcheckinterval(500)
program=sys.argv[0]
here=os.path.join(os.getcwd(), os.path.split(program)[0])
########################################################################
# Configuration section
## General configuration options
##
# This is the IP address of the network interface you want your servers to
# be visible from. This can be changed to '' to listen on all interfaces.
IP_ADDRESS=''
# IP address of your DNS server. Set to '' if you do not want to resolve
# IP addresses. If you have DNS service on your local machine then you can
# set this to '127.0.0.1'
DNS_IP=''
# User id to run ZServer as. Note that this only works under Unix, and if
# ZServer is started by root. This no longer defaults to 'nobody' since
# that can lead to a Zope file compromise.
UID=None
# Log file location. If this is a relative path, then it is joined the
# the 'var' directory.
LOG_FILE='Z2.log'
## HTTP configuration
##
# HTTP enivornment settings.
HTTP_ENV={}
# Port for HTTP Server. The standard port for HTTP services is 80.
HTTP_PORT=8080
## HTTPS configuration
##
# HTTPS enivornment settings.
HTTPS_ENV={}
# Port for HTTP Server. The standard port for HTTP services is 80.
HTTPS_PORT=8443
# Should we close all HTTP connections, ignoring the (usually absent)
# 'Connection:' header?
FORCE_HTTP_CONNECTION_CLOSE=0
# Port for the special "WebDAV source view" HTTP handler. There is no
# standard port for this handler, which is disabled by default.
WEBDAV_SOURCE_PORT=[]
## FTP configuration
# Port for the FTP Server. The standard port for FTP services is 21.
FTP_PORT=8021
## PCGI configuration
# You can configure the PCGI server manually, or have it read its
# configuration information from a PCGI info file.
PCGI_FILE='Zope.cgi'
## Monitor configuration
MONITOR_PORT=0
## ICP configuration
ICP_PORT=0
# Module to be published, which must be Main or Zope
MODULE='Zope'
# The size of the thread pool, if ZODB3 is used.
NUMBER_OF_THREADS=4
# Localization support
LOCALE_ID=None
# Socket path or port for the FastCGI Server
FCGI_PORT=None
# Detailed log file
DETAILED_LOG_FILE=''
# Use a daemon process
USE_DAEMON = 1
#
########################################################################
########################################################################
# Handle command-line arguments:
def server_info(old, v, offset=0):
# interpret v as a port or address/port and get new value
if v == '-': v=''
l=v.find(':')
if l >= 0:
a=v[:l]
v=v[l+1:]
else:
a=IP_ADDRESS
if not v: return v
try:
v=int(v)
if v < 0: raise 'Invalid port', v
v=v+offset
except: raise 'Invalid port', v
if isinstance(old, IntType): old=[(a,v)]
else: old.append((a,v))
return old
try:
python_version = sys.version.split()[0]
if python_version < '2.1':
raise 'Invalid python version', python_version
if python_version[:3] == '2.1':
if python_version[4:5] < '3':
import warnings
err = ('You are running Python version %s. This Python version '
'has known bugs that may cause Zope to run improperly. '
'Consider upgrading to a Python in the 2.1 series '
'with at least version number 2.1.3. (Note that Zope does '
'not yet run under any Python 2.2 version).' %
python_version)
warnings.warn(err)
if python_version[:3] == '2.2':
import warnings
err = ('You are running Python version %s. This Python version '
'has not yet been tested with Zope and you may experience '
'operational problems as a result. Consider using '
'Python 2.1.3 instead.' % python_version)
warnings.warn(err)
opts, args = getopt.getopt(sys.argv[1:],
'hz:Z:t:i:a:d:u:w:y:W:f:p:m:Sl:2DP:rF:L:XM:C',
['icp=', 'force-http-connection-close'
])
DEBUG=0
READ_ONLY=0
if sys.platform == 'win32':
USE_DAEMON = 0
# Get environment variables
for a in args:
if a.find('='):
a=a.split('=')
o=a[0]
v='='.join(a[1:])
if o:
os.environ[o]=v
HTTP_ENV[o]=v
HTTPS_ENV[o]=v
else:
raise 'Invalid argument', a
for o, v in opts:
if o=='-z': here=v
elif o=='-Z':
if v in ('-', '0', ''):
USE_DAEMON=0
elif sys.platform != 'win32':
USE_DAEMON = 1
elif o=='-r': READ_ONLY=1
elif o=='-t':
try: v=int(v)
except: raise 'Invalid number of threads', v
NUMBER_OF_THREADS=v
elif o=='-i':
try: v=int(v)
except: raise 'Invalid value for -i option', v
sys.setcheckinterval(v)
elif o=='-a': IP_ADDRESS=v
elif o=='-d':
if v=='-': v=''
DNS_IP=v
elif o=='-u': UID=v
elif o=='-D':
os.environ['Z_DEBUG_MODE']='1'
DEBUG=1
elif o=='-S': sys.ZMANAGED=1
elif o=='-X':
MONITOR_PORT=HTTP_PORT=HTTPS_PORT=FTP_PORT=FCGI_PORT=ICP_PORT=0
WEBDAV_SOURCE_PORT=0
PCGI_FILE=''
elif o=='-m':
MONITOR_PORT=server_info(MONITOR_PORT, v)
elif o=='-w':
HTTP_PORT=server_info(HTTP_PORT, v)
elif o=='-y':
HTTPS_PORT=server_info(HTTPS_PORT, v)
elif o=='-C' or o=='--force-http-connection-close':
FORCE_HTTP_CONNECTION_CLOSE=1
elif o=='-W':
WEBDAV_SOURCE_PORT=server_info(WEBDAV_SOURCE_PORT, v)
elif o=='-f':
FTP_PORT=server_info(FTP_PORT, v)
elif o=='-P':
HTTP_PORT=server_info(HTTP_PORT, v, 80)
HTTPS_PORT=server_info(HTTPS_PORT, v, 443)
FTP_PORT=server_info(FTP_PORT, v, 21)
elif o=='--icp':
ICP_PORT=server_info(ICP_PORT, v)
elif o=='-p':
if v=='-': v=''
PCGI_FILE=v
elif o=='-h':
print __doc__ % vars()
sys.exit(0)
elif o=='-2': MODULE='Main'
elif o=='-l': LOG_FILE=v
elif o=='-L':
if v: LOCALE_ID=v
else: LOCALE_ID=''
elif o=='-F':
if v=='-': v=''
FCGI_PORT=v
elif o=='-M': DETAILED_LOG_FILE=v
except SystemExit: sys.exit(0)
except:
print __doc__ % vars()
print
print 'Error:'
print "%s: %s" % (sys.exc_type, sys.exc_value)
sys.exit(1)
#
########################################################################
########################################################################
# OK, let's get going!
# Jigger path:
sys.path=[os.path.join(here,'lib','python'),here
]+filter(None, sys.path)
# Try to set the locale if specified on the command
# line. If the locale module is not available or the
# requested locale is not supported by the local
# machine, raise an error so that the user is made
# aware of the problem.
def set_locale(val):
try:
import locale
except:
raise SystemExit, (
'The locale module could not be imported.\n'
'To use localization options, you must ensure\n'
'that the locale module is compiled into your\n'
'Python installation.'
)
try:
locale.setlocale(locale.LC_ALL, val)
except:
raise SystemExit, (
'The specified locale is not supported by your system.\n'
'See your operating system documentation for more\n'
'information on locale support.'
)
if LOCALE_ID is not None:
set_locale(LOCALE_ID)
import zdaemon
# from this point forward we can use the zope logger
# importing ZDaemon before importing ZServer causes ZServer logging
# not to work.
# Import ZServer before we open the database or get at interesting
# application code so that ZServer's asyncore gets to be the
# official one. Also gets SOFTWARE_HOME, INSTANCE_HOME, and CLIENT_HOME
import ZServer
# install signal handlers if on posix
if os.name == 'posix':
from Signals import Signals
Signals.registerZopeSignals()
# Location of the ZServer pid file. When Zope starts up it will write
# its PID to this file. If Zope is run under zdaemon control, zdaemon
# will write to this pidfile instead of Zope.
PID_FILE=os.path.join(CLIENT_HOME, 'Z2.pid')
if USE_DAEMON and not READ_ONLY:
import App.FindHomes
sys.ZMANAGED=1
# zdaemon.run creates a process which "manages" the actual Zope
# process (restarts it if it dies). The management process passes along
# signals that it receives to its child.
zdaemon.run(sys.argv, os.path.join(CLIENT_HOME, PID_FILE))
os.chdir(CLIENT_HOME)
def _warn_nobody():
zLOG.LOG("z2", zLOG.INFO, ("Running Zope as 'nobody' can compromise "
"your Zope files; consider using a "
"dedicated user account for Zope") )
try:
# Import logging support
import zLOG
import ZLogger
if READ_ONLY:
if hasattr(zLOG, '_set_stupid_dest'):
zLOG._set_stupid_dest(sys.stderr)
else:
zLOG._stupid_dest = sys.stderr
else:
zLOG.log_write = ZLogger.ZLogger.log_write
if DETAILED_LOG_FILE:
from ZServer import DebugLogger
logfile=os.path.join(CLIENT_HOME, DETAILED_LOG_FILE)
zLOG.LOG('z2', zLOG.BLATHER,
'Using detailed request log file %s' % logfile)
DL=DebugLogger.DebugLogger(logfile)
DebugLogger.log=DL.log
DebugLogger.reopen=DL.reopen
sys.__detailedlog=DL
# Import Zope (or Main)
if MODULE == 'Zope':
import Zope
Zope.startup()
else:
exec "import "+MODULE in {}
# Location of the ZServer log file. This file logs all ZServer activity.
# You may wish to create different logs for different servers. See
# medusa/logger.py for more information.
if not os.path.isabs(LOG_FILE):
LOG_PATH=os.path.join(CLIENT_HOME, LOG_FILE)
else:
LOG_PATH=LOG_FILE
# import ZServer stuff
# First, we need to increase the number of threads
if MODULE=='Zope':
from ZServer import setNumberOfThreads
setNumberOfThreads(NUMBER_OF_THREADS)
from ZServer import resolver, logger, asyncore
from ZServer import zhttp_server, zhttp_handler
from ZServer.WebDAVSrcHandler import WebDAVSrcHandler
from ZServer import PCGIServer,FTPServer,FCGIServer
from ZServer import secure_monitor_server
## ZServer startup
##
# Resolver and Logger, used by other servers
if DNS_IP:
rs = resolver.caching_resolver(DNS_IP)
else:
rs=None
if READ_ONLY:
lg = logger.file_logger('-') # log to stdout
zLOG.LOG('z2', zLOG.BLATHER, 'Logging access log to stdout')
elif os.environ.has_key('ZSYSLOG_ACCESS'):
if os.environ.has_key("ZSYSLOG_ACCESS_FACILITY"):
lg = logger.syslog_logger(
os.environ['ZSYSLOG_ACCESS'],
facility=os.environ['ZSYSLOG_ACCESS_FACILITY'])
else:
lg = logger.syslog_logger(os.environ['ZSYSLOG_ACCESS'])
zLOG.LOG('z2', zLOG.BLATHER, 'Using local syslog access log')
elif os.environ.has_key('ZSYSLOG_ACCESS_SERVER'):
(addr, port) = os.environ['ZSYSLOG_ACCESS_SERVER'].split( ':')
lg = logger.syslog_logger((addr, int(port)))
zLOG.LOG('z2', zLOG.BLATHER, 'Using remote syslog access log')
else:
lg = logger.file_logger(LOG_PATH)
zLOG.LOG('z2', zLOG.BLATHER, 'Using access log file %s' % LOG_PATH)
sys.__lg = lg
port_err=('\n\nZope wants to use %(socktype)s port %(port)s for its '
'%(protocol)s service, but it is already in use by another '
'application on this machine. Either shut the application down '
'which is using this port, or start Zope with a different '
'%(protocol)s port via the "%(switch)s" command-line switch.\n')
# HTTP Server
if HTTP_PORT:
if isinstance(HTTP_PORT, IntType): HTTP_PORT=((IP_ADDRESS, HTTP_PORT),)
for address, port in HTTP_PORT:
try:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'TCP',
'protocol':'HTTP',
'switch':'-w'}
raise
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
zh = zhttp_handler(MODULE, '', HTTP_ENV)
if FORCE_HTTP_CONNECTION_CLOSE:
zh._force_connection_close = 1
hs.install_handler(zh)
# HTTPS Server
if HTTPS_PORT:
if isinstance(HTTPS_PORT, IntType): HTTPS_PORT=((IP_ADDRESS, HTTPS_PORT),)
for address, port in HTTPS_PORT:
try:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'TCP',
'protocol':'HTTPS',
'switch':'-y'}
raise
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
try:
del HTTPS_ENV['HTTP']
except KeyError:
pass
HTTPS_ENV['HTTPS']='ON'
zh = zhttp_handler(MODULE, '', HTTPS_ENV)
if FORCE_HTTP_CONNECTION_CLOSE:
zh._force_connection_close = 1
hs.install_handler(zh)
# WebDAV source Server (runs HTTP, but munges request to return
# 'manage_FTPget').
if WEBDAV_SOURCE_PORT:
if isinstance(WEBDAV_SOURCE_PORT, IntType):
WEBDAV_SOURCE_PORT=((IP_ADDRESS, WEBDAV_SOURCE_PORT),)
for address, port in WEBDAV_SOURCE_PORT:
try:
hs = zhttp_server(
ip=address,
port=port,
resolver=rs,
logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'TCP',
'protocol':'WebDAV source',
'switch':'-W'}
raise
# Handler for a published module. zhttp_handler takes 3 arguments:
# The name of the module to publish, and optionally the URI base
# which is basically the SCRIPT_NAME, and optionally a dictionary
# with CGI environment variables which override default
# settings. The URI base setting is useful when you want to
# publish more than one module with the same HTTP server. The CGI
# environment setting is useful when you want to proxy requests
# from another web server to ZServer, and would like the CGI
# environment to reflect the CGI environment of the other web
# server.
zh = WebDAVSrcHandler(MODULE, '', HTTP_ENV)
hs.install_handler(zh)
# enable document retrieval of the document source on the
# standard HTTP port
clients = os.environ.get('WEBDAV_SOURCE_PORT_CLIENTS')
if clients:
import re
sys.WEBDAV_SOURCE_PORT_CLIENTS = re.compile(clients).search
else:
sys.WEBDAV_SOURCE_PORT_CLIENTS = None
# FTP Server
if FTP_PORT:
if isinstance(FTP_PORT, IntType): FTP_PORT=((IP_ADDRESS, FTP_PORT),)
for address, port in FTP_PORT:
try:
FTPServer(
module=MODULE,
ip=address,
port=port,
resolver=rs,
logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'TCP',
'protocol':'FTP',
'switch':'-f'}
raise
# PCGI Server
if PCGI_FILE and not READ_ONLY:
PCGI_FILE=os.path.join(here, PCGI_FILE)
if os.path.exists(PCGI_FILE):
zpcgi = PCGIServer(
module=MODULE,
ip=IP_ADDRESS,
pcgi_file=PCGI_FILE,
resolver=rs,
logger_object=lg)
# FastCGI Server
if FCGI_PORT and not READ_ONLY:
fcgiPort = None
fcgiPath = None
try:
fcgiPort = int(FCGI_PORT)
except ValueError:
fcgiPath = FCGI_PORT
try:
zfcgi = FCGIServer(module=MODULE,
ip=IP_ADDRESS,
port=fcgiPort,
socket_file=fcgiPath,
resolver=rs,
logger_object=lg)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':fcgiPort,
'socktype':'TCP',
'protocol':'FastCGI',
'switch':'-F'}
raise
# Monitor Server
if MONITOR_PORT:
from AccessControl.User import emergency_user
if not hasattr(emergency_user, '__null_user__'):
pw = emergency_user._getPassword()
else:
pw = None
zLOG.LOG("z2", zLOG.WARNING, 'Monitor server not started'
' because no emergency user exists.')
if pw:
if isinstance(MONITOR_PORT, IntType):
MONITOR_PORT=((IP_ADDRESS, MONITOR_PORT),)
for address, port in MONITOR_PORT:
try:
monitor=secure_monitor_server(
password=pw,
hostname=address,
port=port)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'TCP',
'protocol':'monitor server',
'switch':'-m'}
raise
if ICP_PORT:
if isinstance(ICP_PORT, IntType): ICP_PORT=((IP_ADDRESS, ICP_PORT),)
from ZServer.ICPServer import ICPServer
for address, port in ICP_PORT:
try:
ICPServer(address,port)
except socket.error, why:
if why[0] == 98: # address in use
raise port_err % {'port':port,
'socktype':'UDP',
'protocol':'ICP',
'switch':'--icp'}
raise
if not USE_DAEMON and not READ_ONLY:
if os.path.exists(PID_FILE): os.unlink(PID_FILE)
pf = open(PID_FILE, 'w')
pid='%s\n' % os.getpid()
pf.write(pid)
pf.close()
# Warn if we were started as nobody.
try:
import pwd
if os.getuid():
if pwd.getpwuid(os.getuid())[0] == 'nobody':
_warn_nobody()
except:
pass
# Drop root privileges if we have them, and do some sanity checking
# to make sure we're not starting with an obviously insecure setup.
try:
if os.getuid() == 0:
try:
import initgroups
except:
raise SystemExit, 'initgroups is required to safely setuid'
if UID == None:
raise SystemExit, ('A user was not specified to setuid '
'to; fix this to start as root (see '
'doc/SETUID.txt)')
import stat
client_home_stat = os.stat(CLIENT_HOME)
client_home_faults = []
if not (client_home_stat[stat.ST_MODE]&01000):
client_home_faults.append('does not have the sticky bit set')
if client_home_stat[stat.ST_UID] != 0:
client_home_faults.append('is not owned by root')
if client_home_faults:
client_home_faults.append('fix this to start as root (see '
'doc/SETUID.txt)')
err = '%s %s' % (CLIENT_HOME, ', '.join(client_home_faults))
raise SystemExit, err
try:
try: UID = string.atoi(UID)
except: pass
gid = None
if isinstance(UID, StringType):
uid = pwd.getpwnam(UID)[2]
gid = pwd.getpwnam(UID)[3]
elif isinstance(UID, IntType):
uid = pwd.getpwuid(UID)[2]
gid = pwd.getpwuid(UID)[3]
UID = pwd.getpwuid(UID)[0]
else:
raise KeyError
if UID == 'nobody':
_warn_nobody()
try:
initgroups.initgroups(UID, gid)
if gid is not None:
try:
os.setgid(gid)
except OSError:
pass
os.setuid(uid)
except OSError:
pass
except KeyError:
zLOG.LOG("z2", zLOG.ERROR, ("Can't find UID %s" % UID))
except AttributeError:
pass
except:
raise
# Check umask sanity if we're on posix.
if os.name == 'posix' and not os.environ.get('Z_DEBUG_MODE'):
# umask is silly, blame POSIX. We have to set it to get its value.
current_umask = os.umask(0)
os.umask(current_umask)
if current_umask != 077:
current_umask = '%03o' % current_umask
zLOG.LOG("z2", zLOG.INFO, (
'Your umask of %s may be too permissive; for the security of '
'your Zope data, it is recommended you use 077' % current_umask
))
except:
# Log startup exception and tell zdaemon not to restart us.
try:
zLOG.LOG("z2", zLOG.PANIC, "Startup exception",
error=sys.exc_info())
except: pass
sys.exit(0)
# Start Medusa, Ye Hass!
sys.ZServerExitCode=0
asyncore.loop()
sys.exit(sys.ZServerExitCode)
Pound-2.8/config.sub 0000755 0001750 0001750 00000072474 13275266545 013510 0 ustar roseg roseg #! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
timestamp='2003-05-09'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Please send patches to . Submit a context
# diff and a properly formatted ChangeLog entry.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
# If it is invalid, we print an error message on stderr and exit with code 1.
# Otherwise, we print the canonical config type on stdout and succeed.
# This file is supposed to be the same for all GNU packages
# and recognize all the CPU types, system types and aliases
# that are meaningful with *any* GNU software.
# Each package is responsible for reporting which valid configurations
# it does not support. The user should be able to distinguish
# a failure to support a valid configuration from a meaningless
# configuration.
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or in some cases, the newer four-part form:
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
me=`echo "$0" | sed -e 's,.*/,,'`
usage="\
Usage: $0 [OPTION] CPU-MFR-OPSYS
$0 [OPTION] ALIAS
Canonicalize a configuration name.
Operation modes:
-h, --help print this help, then exit
-t, --time-stamp print date of last modification, then exit
-v, --version print version number, then exit
Report bugs and patches to ."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
help="
Try \`$me --help' for more information."
# Parse command line
while test $# -gt 0 ; do
case $1 in
--time-stamp | --time* | -t )
echo "$timestamp" ; exit 0 ;;
--version | -v )
echo "$version" ; exit 0 ;;
--help | --h* | -h )
echo "$usage"; exit 0 ;;
-- ) # Stop option processing
shift; break ;;
- ) # Use stdin as input.
break ;;
-* )
echo "$me: invalid option $1$help"
exit 1 ;;
*local*)
# First pass through any local machine types.
echo $1
exit 0;;
* )
break ;;
esac
done
case $# in
0) echo "$me: missing argument$help" >&2
exit 1;;
1) ;;
*) echo "$me: too many arguments$help" >&2
exit 1;;
esac
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | freebsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
then os=`echo $1 | sed 's/.*-/-/'`
else os=; fi
;;
esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
### recognize some manufacturers as not being operating systems, so we
### can provide default operating systems below.
case $os in
-sun*os*)
# Prevent following clause from handling this invalid input.
;;
-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis)
os=
basic_machine=$1
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
basic_machine=$1
;;
-scout)
;;
-wrs)
os=-vxworks
basic_machine=$1
;;
-chorusos*)
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
-sco5)
os=-sco3.2v5
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco4)
os=-sco3.2v4
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-udk*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
;;
-ptx*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
;;
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
-psos*)
os=-psos
;;
-mint | -mint[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
| clipper \
| d10v | d30v | dlx | dsp16xx \
| fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| i370 | i860 | i960 | ia64 \
| ip2k \
| m32r | m68000 | m68k | m88k | mcore \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
| mips64vr | mips64vrel \
| mips64orion | mips64orionel \
| mips64vr4100 | mips64vr4100el \
| mips64vr4300 | mips64vr4300el \
| mips64vr5000 | mips64vr5000el \
| mipsisa32 | mipsisa32el \
| mipsisa32r2 | mipsisa32r2el \
| mipsisa64 | mipsisa64el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| msp430 \
| ns16k | ns32k \
| openrisc | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| pyramid \
| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
| strongarm \
| tahoe | thumb | tic80 | tron \
| v850 | v850e \
| we32k \
| x86 | xscale | xstormy16 | xtensa \
| z8k)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12)
# Motorola 68HC11/12.
basic_machine=$basic_machine-unknown
os=-none
;;
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
i*86 | x86_64)
basic_machine=$basic_machine-pc
;;
# Object if more than one company name word.
*-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* \
| bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* \
| m32r-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | mcore-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
| mips64vr-* | mips64vrel-* \
| mips64orion-* | mips64orionel-* \
| mips64vr4100-* | mips64vr4100el-* \
| mips64vr4300-* | mips64vr4300el-* \
| mips64vr5000-* | mips64vr5000el-* \
| mipsisa32-* | mipsisa32el-* \
| mipsisa32r2-* | mipsisa32r2el-* \
| mipsisa64-* | mipsisa64el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipstx39-* | mipstx39el-* \
| msp430-* \
| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| pyramid-* \
| romp-* | rs6000-* \
| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tron-* \
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
| xtensa-* \
| ymp-* \
| z8k-*)
;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
basic_machine=i386-unknown
os=-bsd
;;
3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
basic_machine=m68000-att
;;
3b*)
basic_machine=we32k-att
;;
a29khif)
basic_machine=a29k-amd
os=-udi
;;
adobe68k)
basic_machine=m68010-adobe
os=-scout
;;
alliant | fx80)
basic_machine=fx80-alliant
;;
altos | altos3068)
basic_machine=m68k-altos
;;
am29k)
basic_machine=a29k-none
os=-bsd
;;
amd64)
basic_machine=x86_64-pc
;;
amdahl)
basic_machine=580-amdahl
os=-sysv
;;
amiga | amiga-*)
basic_machine=m68k-unknown
;;
amigaos | amigados)
basic_machine=m68k-unknown
os=-amigaos
;;
amigaunix | amix)
basic_machine=m68k-unknown
os=-sysv4
;;
apollo68)
basic_machine=m68k-apollo
os=-sysv
;;
apollo68bsd)
basic_machine=m68k-apollo
os=-bsd
;;
aux)
basic_machine=m68k-apple
os=-aux
;;
balance)
basic_machine=ns32k-sequent
os=-dynix
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
convex-c1)
basic_machine=c1-convex
os=-bsd
;;
convex-c2)
basic_machine=c2-convex
os=-bsd
;;
convex-c32)
basic_machine=c32-convex
os=-bsd
;;
convex-c34)
basic_machine=c34-convex
os=-bsd
;;
convex-c38)
basic_machine=c38-convex
os=-bsd
;;
cray | j90)
basic_machine=j90-cray
os=-unicos
;;
crds | unos)
basic_machine=m68k-crds
;;
cris | cris-* | etrax*)
basic_machine=cris-axis
;;
da30 | da30-*)
basic_machine=m68k-da30
;;
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
basic_machine=mips-dec
;;
decsystem10* | dec10*)
basic_machine=pdp10-dec
os=-tops10
;;
decsystem20* | dec20*)
basic_machine=pdp10-dec
os=-tops20
;;
delta | 3300 | motorola-3300 | motorola-delta \
| 3300-motorola | delta-motorola)
basic_machine=m68k-motorola
;;
delta88)
basic_machine=m88k-motorola
os=-sysv3
;;
dpx20 | dpx20-*)
basic_machine=rs6000-bull
os=-bosx
;;
dpx2* | dpx2*-bull)
basic_machine=m68k-bull
os=-sysv3
;;
ebmon29k)
basic_machine=a29k-amd
os=-ebmon
;;
elxsi)
basic_machine=elxsi-elxsi
os=-bsd
;;
encore | umax | mmax)
basic_machine=ns32k-encore
;;
es1800 | OSE68k | ose68k | ose | OSE)
basic_machine=m68k-ericsson
os=-ose
;;
fx2800)
basic_machine=i860-alliant
;;
genix)
basic_machine=ns32k-ns
;;
gmicro)
basic_machine=tron-gmicro
os=-sysv
;;
go32)
basic_machine=i386-pc
os=-go32
;;
h3050r* | hiux*)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
h8300hms)
basic_machine=h8300-hitachi
os=-hms
;;
h8300xray)
basic_machine=h8300-hitachi
os=-xray
;;
h8500hms)
basic_machine=h8500-hitachi
os=-hms
;;
harris)
basic_machine=m88k-harris
os=-sysv3
;;
hp300-*)
basic_machine=m68k-hp
;;
hp300bsd)
basic_machine=m68k-hp
os=-bsd
;;
hp300hpux)
basic_machine=m68k-hp
os=-hpux
;;
hp3k9[0-9][0-9] | hp9[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k2[0-9][0-9] | hp9k31[0-9])
basic_machine=m68000-hp
;;
hp9k3[2-9][0-9])
basic_machine=m68k-hp
;;
hp9k6[0-9][0-9] | hp6[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hp9k7[0-79][0-9] | hp7[0-79][0-9])
basic_machine=hppa1.1-hp
;;
hp9k78[0-9] | hp78[0-9])
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
# FIXME: really hppa2.0-hp
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][13679] | hp8[0-9][13679])
basic_machine=hppa1.1-hp
;;
hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp
;;
hppa-next)
os=-nextstep3
;;
hppaosf)
basic_machine=hppa1.1-hp
os=-osf
;;
hppro)
basic_machine=hppa1.1-hp
os=-proelf
;;
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
i*86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
i*86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
i*86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
i386mach)
basic_machine=i386-mach
os=-mach
;;
i386-vsta | vsta)
basic_machine=i386-unknown
os=-vsta
;;
iris | iris4d)
basic_machine=mips-sgi
case $os in
-irix*)
;;
*)
os=-irix4
;;
esac
;;
isi68 | isi)
basic_machine=m68k-isi
os=-sysv
;;
m88k-omron*)
basic_machine=m88k-omron
;;
magnum | m3230)
basic_machine=mips-mips
os=-sysv
;;
merlin)
basic_machine=ns32k-utek
os=-sysv
;;
mingw32)
basic_machine=i386-pc
os=-mingw32
;;
miniframe)
basic_machine=m68000-convergent
;;
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
basic_machine=m68k-atari
os=-mint
;;
mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;;
mips3*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
;;
mmix*)
basic_machine=mmix-knuth
os=-mmixware
;;
monitor)
basic_machine=m68k-rom68k
os=-coff
;;
morphos)
basic_machine=powerpc-unknown
os=-morphos
;;
msdos)
basic_machine=i386-pc
os=-msdos
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
;;
netbsd386)
basic_machine=i386-unknown
os=-netbsd
;;
netwinder)
basic_machine=armv4l-rebel
os=-linux
;;
news | news700 | news800 | news900)
basic_machine=m68k-sony
os=-newsos
;;
news1000)
basic_machine=m68030-sony
os=-newsos
;;
news-3600 | risc-news)
basic_machine=mips-sony
os=-newsos
;;
necv70)
basic_machine=v70-nec
os=-sysv
;;
next | m*-next )
basic_machine=m68k-next
case $os in
-nextstep* )
;;
-ns2*)
os=-nextstep2
;;
*)
os=-nextstep3
;;
esac
;;
nh3000)
basic_machine=m68k-harris
os=-cxux
;;
nh[45]000)
basic_machine=m88k-harris
os=-cxux
;;
nindy960)
basic_machine=i960-intel
os=-nindy
;;
mon960)
basic_machine=i960-intel
os=-mon960
;;
nonstopux)
basic_machine=mips-compaq
os=-nonstopux
;;
np1)
basic_machine=np1-gould
;;
nv1)
basic_machine=nv1-cray
os=-unicosmp
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
op50n-* | op60c-*)
basic_machine=hppa1.1-oki
os=-proelf
;;
or32 | or32-*)
basic_machine=or32-unknown
os=-coff
;;
OSE68000 | ose68000)
basic_machine=m68000-ericsson
os=-ose
;;
os68k)
basic_machine=m68k-none
os=-os68k
;;
pa-hitachi)
basic_machine=hppa1.1-hitachi
os=-hiuxwe2
;;
paragon)
basic_machine=i860-intel
os=-osf
;;
pbd)
basic_machine=sparc-tti
;;
pbb)
basic_machine=m68k-tti
;;
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
pentium | p5 | k5 | k6 | nexgen | viac3)
basic_machine=i586-pc
;;
pentiumpro | p6 | 6x86 | athlon | athlon_*)
basic_machine=i686-pc
;;
pentiumii | pentium2)
basic_machine=i686-pc
;;
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumpro-* | p6-* | 6x86-* | athlon-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pentiumii-* | pentium2-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
pn)
basic_machine=pn-gould
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
;;
ppcle-* | powerpclittle-*)
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64) basic_machine=powerpc64-unknown
;;
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
basic_machine=powerpc64le-unknown
;;
ppc64le-* | powerpc64little-*)
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ps2)
basic_machine=i386-ibm
;;
pw32)
basic_machine=i586-unknown
os=-pw32
;;
rom68k)
basic_machine=m68k-rom68k
os=-coff
;;
rm[46]00)
basic_machine=mips-siemens
;;
rtpc | rtpc-*)
basic_machine=romp-ibm
;;
s390 | s390-*)
basic_machine=s390-ibm
;;
s390x | s390x-*)
basic_machine=s390x-ibm
;;
sa29200)
basic_machine=a29k-amd
os=-udi
;;
sb1)
basic_machine=mipsisa64sb1-unknown
;;
sb1el)
basic_machine=mipsisa64sb1el-unknown
;;
sequent)
basic_machine=i386-sequent
;;
sh)
basic_machine=sh-hitachi
os=-hms
;;
sparclite-wrs | simso-wrs)
basic_machine=sparclite-wrs
os=-vxworks
;;
sps7)
basic_machine=m68k-bull
os=-sysv2
;;
spur)
basic_machine=spur-unknown
;;
st2000)
basic_machine=m68k-tandem
;;
stratus)
basic_machine=i860-stratus
os=-sysv4
;;
sun2)
basic_machine=m68000-sun
;;
sun2os3)
basic_machine=m68000-sun
os=-sunos3
;;
sun2os4)
basic_machine=m68000-sun
os=-sunos4
;;
sun3os3)
basic_machine=m68k-sun
os=-sunos3
;;
sun3os4)
basic_machine=m68k-sun
os=-sunos4
;;
sun4os3)
basic_machine=sparc-sun
os=-sunos3
;;
sun4os4)
basic_machine=sparc-sun
os=-sunos4
;;
sun4sol2)
basic_machine=sparc-sun
os=-solaris2
;;
sun3 | sun3-*)
basic_machine=m68k-sun
;;
sun4)
basic_machine=sparc-sun
;;
sun386 | sun386i | roadrunner)
basic_machine=i386-sun
;;
sv1)
basic_machine=sv1-cray
os=-unicos
;;
symmetry)
basic_machine=i386-sequent
os=-dynix
;;
t3e)
basic_machine=alphaev5-cray
os=-unicos
;;
t90)
basic_machine=t90-cray
os=-unicos
;;
tic4x | c4x*)
basic_machine=tic4x-unknown
os=-coff
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
toad1)
basic_machine=pdp10-xkl
os=-tops20
;;
tower | tower-32)
basic_machine=m68k-ncr
;;
udi29k)
basic_machine=a29k-amd
os=-udi
;;
ultra3)
basic_machine=a29k-nyu
os=-sym1
;;
v810 | necv810)
basic_machine=v810-nec
os=-none
;;
vaxv)
basic_machine=vax-dec
os=-sysv
;;
vms)
basic_machine=vax-dec
os=-vms
;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960)
basic_machine=i960-wrs
os=-vxworks
;;
vxworks68)
basic_machine=m68k-wrs
os=-vxworks
;;
vxworks29k)
basic_machine=a29k-wrs
os=-vxworks
;;
w65*)
basic_machine=w65-wdc
os=-none
;;
w89k-*)
basic_machine=hppa1.1-winbond
os=-proelf
;;
xps | xps100)
basic_machine=xps100-honeywell
;;
ymp)
basic_machine=ymp-cray
os=-unicos
;;
z8k-*-coff)
basic_machine=z8k-unknown
os=-sim
;;
none)
basic_machine=none-none
os=-none
;;
# Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular.
w89k)
basic_machine=hppa1.1-winbond
;;
op50n)
basic_machine=hppa1.1-oki
;;
op60c)
basic_machine=hppa1.1-oki
;;
romp)
basic_machine=romp-ibm
;;
rs6000)
basic_machine=rs6000-ibm
;;
vax)
basic_machine=vax-dec
;;
pdp10)
# there are many clones, so DEC is not a safe bet
basic_machine=pdp10-unknown
;;
pdp11)
basic_machine=pdp11-dec
;;
we32k)
basic_machine=we32k-att
;;
sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
basic_machine=sh-unknown
;;
sh64)
basic_machine=sh64-unknown
;;
sparc | sparcv9 | sparcv9b)
basic_machine=sparc-sun
;;
cydra)
basic_machine=cydra-cydrome
;;
orion)
basic_machine=orion-highlevel
;;
orion105)
basic_machine=clipper-highlevel
;;
mac | mpw | mac-mpw)
basic_machine=m68k-apple
;;
pmac | pmac-mpw)
basic_machine=powerpc-apple
;;
*-unknown)
# Make sure to match an already-canonicalized machine name.
;;
*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1
;;
esac
# Here we canonicalize certain aliases for manufacturers.
case $basic_machine in
*-digital*)
basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
;;
*-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;;
*)
;;
esac
# Decode manufacturer-specific aliases for certain operating systems.
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
;;
-solaris)
os=-solaris2
;;
-svr4*)
os=-sysv4
;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
# Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
case $basic_machine in
x86-* | i*86-*)
;;
*)
os=-nto$os
;;
esac
;;
-nto-qnx*)
;;
-nto*)
os=`echo $os | sed -e 's|nto|nto-qnx|'`
;;
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
;;
-mac*)
os=`echo $os | sed -e 's|mac|macos|'`
;;
-linux*)
os=`echo $os | sed -e 's|linux|linux-gnu|'`
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
;;
-sunos6*)
os=`echo $os | sed -e 's|sunos6|solaris3|'`
;;
-opened*)
os=-openedition
;;
-wince*)
os=-wince
;;
-osfrose*)
os=-osfrose
;;
-osf*)
os=-osf
;;
-utek*)
os=-bsd
;;
-dynix*)
os=-bsd
;;
-acis*)
os=-aos
;;
-atheos*)
os=-atheos
;;
-386bsd)
os=-bsd
;;
-ctix* | -uts*)
os=-sysv
;;
-nova*)
os=-rtmk-nova
;;
-ns2 )
os=-nextstep2
;;
-nsk*)
os=-nsk
;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
;;
-sinix*)
os=-sysv4
;;
-triton*)
os=-sysv3
;;
-oss*)
os=-sysv3
;;
-svr4)
os=-sysv4
;;
-svr3)
os=-sysv3
;;
-sysvr4)
os=-sysv4
;;
# This must come after -sysvr4.
-sysv*)
;;
-ose*)
os=-ose
;;
-es1800*)
os=-ose
;;
-xenix)
os=-xenix
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
os=-mint
;;
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-none)
;;
*)
# Get rid of the `-' at the beginning of $os.
os=`echo $os | sed 's/[^-]*-//'`
echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
exit 1
;;
esac
else
# Here we handle the default operating systems that come with various machines.
# The value should be what the vendor currently ships out the door with their
# machine or put another way, the most popular os provided with the machine.
# Note that if you're going to try to match "-MANUFACTURER" here (say,
# "-sun"), then you have to tell the case statement up towards the top
# that MANUFACTURER isn't an operating system. Otherwise, code above
# will signal an error saying that MANUFACTURER isn't an operating
# system, and we'll never get to this point.
case $basic_machine in
*-acorn)
os=-riscix1.2
;;
arm*-rebel)
os=-linux
;;
arm*-semi)
os=-aout
;;
# This must come before the *-dec entry.
pdp10-*)
os=-tops20
;;
pdp11-*)
os=-none
;;
*-dec | vax-*)
os=-ultrix4.2
;;
m68*-apollo)
os=-domain
;;
i386-sun)
os=-sunos4.0.2
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mips*-cisco)
os=-elf
;;
mips*-*)
os=-elf
;;
or32-*)
os=-coff
;;
*-tti) # must be before sparc entry or we get the wrong os.
os=-sysv3
;;
sparc-* | *-sun)
os=-sunos4.1.1
;;
*-be)
os=-beos
;;
*-ibm)
os=-aix
;;
*-wec)
os=-proelf
;;
*-winbond)
os=-proelf
;;
*-oki)
os=-proelf
;;
*-hp)
os=-hpux
;;
*-hitachi)
os=-hiux
;;
i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
os=-sysv
;;
*-cbm)
os=-amigaos
;;
*-dg)
os=-dgux
;;
*-dolphin)
os=-sysv3
;;
m68k-ccur)
os=-rtu
;;
m88k-omron*)
os=-luna
;;
*-next )
os=-nextstep
;;
*-sequent)
os=-ptx
;;
*-crds)
os=-unos
;;
*-ns)
os=-genix
;;
i370-*)
os=-mvs
;;
*-next)
os=-nextstep3
;;
*-gould)
os=-sysv
;;
*-highlevel)
os=-bsd
;;
*-encore)
os=-bsd
;;
*-sgi)
os=-irix
;;
*-siemens)
os=-sysv4
;;
*-masscomp)
os=-rtu
;;
f30[01]-fujitsu | f700-fujitsu)
os=-uxpv
;;
*-rom68k)
os=-coff
;;
*-*bug)
os=-coff
;;
*-apple)
os=-macos
;;
*-atari*)
os=-mint
;;
*)
os=-none
;;
esac
fi
# Here we handle the case where we know the os, and the CPU type, but not the
# manufacturer. We pick the logical manufacturer.
vendor=unknown
case $basic_machine in
*-unknown)
case $os in
-riscix*)
vendor=acorn
;;
-sunos*)
vendor=sun
;;
-aix*)
vendor=ibm
;;
-beos*)
vendor=be
;;
-hpux*)
vendor=hp
;;
-mpeix*)
vendor=hp
;;
-hiux*)
vendor=hitachi
;;
-unos*)
vendor=crds
;;
-dgux*)
vendor=dg
;;
-luna*)
vendor=omron
;;
-genix*)
vendor=ns
;;
-mvs* | -opened*)
vendor=ibm
;;
-ptx*)
vendor=sequent
;;
-vxsim* | -vxworks* | -windiss*)
vendor=wrs
;;
-aux*)
vendor=apple
;;
-hms*)
vendor=hitachi
;;
-mpw* | -macos*)
vendor=apple
;;
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
vendor=atari
;;
-vos*)
vendor=stratus
;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
esac
echo $basic_machine$os
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "timestamp='"
# time-stamp-format: "%:y-%02m-%02d"
# time-stamp-end: "'"
# End:
Pound-2.8/CHANGELOG 0000664 0001750 0001750 00000077361 13275266545 012741 0 ustar roseg roseg ------------------------------------------------------------------------
r83 | roseg | 2018-05-11 12:16:05 +0200 (Fri, 11 May 2018) | 9 lines
Release 2.8
Enhancements:
- removed DynScale flag and support
- removed support for multi-line headers (both input and output)
Bug fixes:
- fixed potential request smuggling via fudged headers
------------------------------------------------------------------------
r82 | roseg | 2016-10-23 16:59:47 +0200 (Sun, 23 Oct 2016) | 8 lines
Release 2.8a
Enhancements:
- removed DynScale flag and support
Bug fixes:
- fixed potential request smuggling via fudged headers
------------------------------------------------------------------------
r81 | roseg | 2015-01-26 17:47:53 +0100 (Mon, 26 Jan 2015) | 30 lines
Release 2.7
Enhancements:
- added support for larger DH keys + compile-time parameter for DH bits (workaround for OpenSSL limitation)
- added support for elliptical curve encryption
- added protocol version in X-SSL-cipher (Tom Fitzhenry)
- added "Disable PROTO" directives (fix for Poodle vulnerability)
- added Cert, Disable and Cipher directives for HTTPS back-ends. The directive HTTPS "cert" no longer supported.
- added filtering of "Expect: 100-continue" headers
- Add support for PATCH HTTP method
- Anonymise configuration option - show last client address byte as 0 (based on an idea by Christian Doering)
- SSLAllowClientRenegotiation (based on a patch from Joe Gooch)
- SSLHonorCipherOrder (based on a patch from Joe Gooch)
- Certificate alternate names support (based on a patch from Jonas Pasche)
- poundctl shows the length of the request queue (based on a request from Leo)
Bug fixes:
- fixed lh_retrieve warning
- fixed potential memory leak on client certificates
- fixed alt names problem (Joe Gooch)
- removed debugging messages
- fixed address comparison for RewriteLocation (IPv4/IPv6 problem - Christopher Bartz)
- re-patched the redirect patch (Frank Schmierler)
- fixed RPC handling (Frank Schmierler)
- sanitize URLs for redirection (prevent CSRF)
- SSL disable empty fragments + SSL disable compression (CRIME attack prevention)
- fixed bug in configuration of DISABLED directive
- changed the log level from WARNING to NOTICE if the thread arg is NULL
- fixed testing of gcc options
------------------------------------------------------------------------
r80 | roseg | 2014-12-29 11:47:54 +0100 (Mon, 29 Dec 2014) | 10 lines
Release 2.7f
Enhancements:
- compile-time parameter for DH bits (workaround for OpenSSL limitation)
Bug fixes:
- allow '-' and '=' again in URLs (redirect)
- fixed lh_retrieve warning
- fixed "Disable" regex typo
------------------------------------------------------------------------
r79 | roseg | 2014-12-08 14:39:00 +0100 (Mon, 08 Dec 2014) | 12 lines
Release 2.7e
Enhancements:
- added support for elliptical curve encryption
- added support for larger DH keys
- added protocol version in X-SSL-cipher (Tom Fitzhenry)
Bug fixes:
- fixed potential memory leak on client certificates
- fixed alt names problem (Joe Gooch)
- removed debugging messages
------------------------------------------------------------------------
r78 | roseg | 2014-10-18 12:36:28 +0200 (Sat, 18 Oct 2014) | 10 lines
Release 2.7d
Enhancements:
- added "Disable PROTO" directives (fix for Poodle vulnerability)
- added Cert, Disable and Cipher directives for HTTPS back-ends. The
directive HTTPS "cert" no longer supported.
Bug fixes:
- fixed address comparison for RewriteLocation (IPv4/IPv6 problem - Christopher Bartz)
------------------------------------------------------------------------
r77 | roseg | 2014-04-21 13:16:07 +0200 (Mon, 21 Apr 2014) | 9 lines
Release 2.7c
Enhancements:
- added filtering of "Expect: 100-continue" headers
Bug fixes:
- re-patched the redirect patch (Frank Schmierler)
- fixed RPC handling (Frank Schmierler)
------------------------------------------------------------------------
r76 | roseg | 2013-09-26 14:33:21 +0200 (Thu, 26 Sep 2013) | 12 lines
Release 2.7b
Enhancements:
- Add support for PATCH HTTP method
Bug fixes:
- sanitize URLs for redirection (prevent CSRF)
- SSL disable empty fragments
- SSL disable compression (CRIME attack prevention)
- fixed bug in configuration of DISABLED directive
- changed the log level from WARNING to NOTICE if the thread arg is NULL
------------------------------------------------------------------------
r75 | roseg | 2012-04-09 15:37:26 +0200 (Mon, 09 Apr 2012) | 12 lines
Release 2.7a
Enhancements:
- Anonymise configuration option - show last client address byte as 0 (based on an idea by Christian Doering)
- SSLAllowClientRenegotiation (based on a patch from Joe Gooch)
- SSLHonorCipherOrder (based on a patch from Joe Gooch)
- Certificate alternate names support (based on a patch from Jonas Pasche)
- poundctl shows the length of the request queue (based on a request from Leo)
Bug fixes:
- fixed testing of gcc options
------------------------------------------------------------------------
r74 | roseg | 2011-12-28 14:57:45 +0100 (Wed, 28 Dec 2011) | 10 lines
Release 2.6
Enhancements:
- allow multiple AddHeader directives
Bug fixes:
- fixed memory leak in config/AddHeader
- removed call to AC_FUNC_MALLOC for AIX compatability
- workaround for AIX getaddrinfo() bug
------------------------------------------------------------------------
r73 | roseg | 2011-06-24 17:59:41 +0200 (Fri, 24 Jun 2011) | 7 lines
Release 2.6f
Enhancements:
Bug fixes:
- fixed memory leak in DH (patch by Edvin Torok via Patrizio Tassone)
------------------------------------------------------------------------
r72 | roseg | 2011-04-25 11:10:45 +0200 (Mon, 25 Apr 2011) | 8 lines
Release 2.6e
Enhancements:
Bug fixes:
- fixed problem in SNI certificate storage
- changed long to long long for support of requests larger than 2GB
------------------------------------------------------------------------
r71 | roseg | 2011-04-11 15:59:05 +0200 (Mon, 11 Apr 2011) | 9 lines
Release 2.6d
Enhancements:
- added parsing for certificate CN
Bug fixes:
- fixed problem in task enqueing
- fixed small problem in Makefile
------------------------------------------------------------------------
r70 | roseg | 2010-12-27 17:54:18 +0100 (Mon, 27 Dec 2010) | 14 lines
Release 2.6c
Enhancements:
- added support for OpenSSL 1.0
- added some more detailed error logging
Bug fixes:
- fix for RewriteLocation
- fix for HTTPS back-ends
- fix for RPC support
- fix for possible request smuggling by using multiple headers
Many thanks to Frank Schmirler and Ruben Kerkhof for the contributed patches
------------------------------------------------------------------------
r69 | roseg | 2010-09-25 16:49:49 +0200 (Sat, 25 Sep 2010) | 7 lines
Release 2.6b
Enhancements:
- pre-defined number of threads for better performance on small hardware
Bug fixes:
------------------------------------------------------------------------
r68 | roseg | 2010-06-23 19:18:39 +0200 (Wed, 23 Jun 2010) | 15 lines
Release 2.6a
Stable release 2.5.1
Enhancements:
- support for SNI via multiple Cert directives (thanks to Joe Gooch)
- translate hexadecimal characters in URL for pattern matching
- added support for a "Disabled" directive in the configuration
Bug fixes:
- keep sessions for disabled back-ends, continue using them until the time-out
- fixed memory leak in session removal
- user IgnoreCase for CheckURL too
- fixed some issues with OpenSolaris build (thanks to Spradling Cloyce)
------------------------------------------------------------------------
r67 | roseg | 2010-02-02 12:49:00 +0100 (Tue, 02 Feb 2010) | 9 lines
Release 2.5
Enhancements:
Bug fixes:
- fixed XML format to avoid problems with brain-dead parsers
- fixed Redirect to accept "/" as a path, so that "Redirect http://x/" is
considered an absolute path, but "Redirect http://x" is not
------------------------------------------------------------------------
r66 | roseg | 2010-01-04 17:20:55 +0100 (Mon, 04 Jan 2010) | 7 lines
Release 2.5e
Enhancements:
- added support for symbolic host names in poundctl
Bug fixes:
------------------------------------------------------------------------
r65 | roseg | 2009-12-07 17:01:21 +0100 (Mon, 07 Dec 2009) | 9 lines
Release 2.5d
Enhancements:
- added support for --disable-pcreposix, --disable--tcmalloc, --disable-hoard in configuration script
Bug fixes:
- fixed problem with long input lines in http.c
- if libpcreposix is present, then pcreposix.h must also be present
------------------------------------------------------------------------
r64 | roseg | 2009-09-21 13:16:57 +0200 (Mon, 21 Sep 2009) | 8 lines
Release 2.5c
Enhancements:
- added support for HTTPS backends
Bug fixes:
- fixed problem with sub-patterns in session parameters
------------------------------------------------------------------------
r63 | roseg | 2009-08-19 17:44:07 +0200 (Wed, 19 Aug 2009) | 10 lines
Release 2.5b
Enhancements:
- support for ConnTO directive
- support for IgnoreCase directive
Bug fixes:
- fixed problem in conf_fgets (\n confuses the regexp)
- changed RSA ephemeral keys regeneration default time (every 30 minutes)
------------------------------------------------------------------------
r62 | roseg | 2009-08-06 17:23:30 +0200 (Thu, 06 Aug 2009) | 9 lines
Release 2.5a
Enhancements:
- support for include directive
Bug fixes:
- fixed generation of ephemeral RSA keys (avoid premature locking)
- added pre-generated DH parameters
------------------------------------------------------------------------
r61 | roseg | 2009-06-29 17:53:55 +0200 (Mon, 29 Jun 2009) | 13 lines
Release 2.4.5
Stable release 2.4.5
Enhancements:
- log back-end killed/disabled/enabled (thanks to Joe Gooch and Jon Garvin)
- kill a BE on connection failure only if it has no HAport defined (thanks to Albert); the request may still fail!
Bug fixes:
- fixed parantheses problems in need_rewrite (thanks to SBR)
- added call to free_headers in http.c (thanks to SBR)
- fixed maximal path length in UNIX domain sockets (thanks to Ricardo Gameiro)
------------------------------------------------------------------------
r60 | roseg | 2009-01-14 17:39:52 +0100 (Wed, 14 Jan 2009) | 18 lines
Release 2.4.4
Stable release 2.4.4
Enhancements:
- added support for UNSUBSCRIBE and NOTIFY in xHTTP 3 and 4
- added support for BPROPFIND in xHTTP 4
- on SSL connections always pass the cipher used to the back-end (thanks to Magnus Sandin)
Bug fixes:
- save and restore errno value in cur_time() (thanks to Albert)
- fixed problem in timer thread (thanks to Albert)
- added shutdown for failed socket connection (thanks to Albert)
- fixed problem with CC containing spaces in Makefile.in (thanks to Elan Ruusamäe)
- increased MAXBUF to default 4096
- increased T_RSA default to 30 minutes
- fixed a problem with Unix sockets back-ends (thanks to Ricardo Gameiro)
------------------------------------------------------------------------
r59 | roseg | 2008-05-31 12:25:41 +0200 (Sat, 31 May 2008) | 11 lines
Release 2.4.3
Stable release 2.4.3
Enhancements:
Bug fixes:
- fixed problem in session access time updating (thanks to Piotr Jakubowski)
- fixed problem in session removal (thanks to Doriam Mori)
- fixed problem in Redirect logging (thanks to Albert)
------------------------------------------------------------------------
r58 | roseg | 2008-04-24 16:31:28 +0200 (Thu, 24 Apr 2008) | 13 lines
Release 2.4.2
Stable release 2.4.2
Enhancements:
Bug fixes:
- fixed problem with session TTL -1 (thanks to Scott Royston for pointing it out)
- fixed problem with back-end killing on failed connect
- fixed a small problem in the poundctl XML output (thanks to johnlr for the fix)
- added hints in call to getaddrinfo() (for Solaris 10 support)
- fixed redirection problem (missing slash in Location/Content-location)
------------------------------------------------------------------------
r57 | roseg | 2008-04-05 11:45:41 +0200 (Sat, 05 Apr 2008) | 12 lines
Release 2.4.1
Stable release 2.4.1
Enhancements:
- added cache control for errors (thanks to Pavel Merdin for the suggestion)
Bug fixes:
- fixed problem with double slash in header rewriting (thanks to Cédric P.)
- remove sched_policy to avoid problems on systems with poor support for it
- fixed memory corruption problem with HAport
------------------------------------------------------------------------
r56 | roseg | 2008-02-11 12:53:51 +0100 (Mon, 11 Feb 2008) | 4 lines
Release 2.4
Stable release 2.4
------------------------------------------------------------------------
r55 | roseg | 2007-12-27 12:54:32 +0100 (Thu, 27 Dec 2007) | 7 lines
Release 2.4f
Enhancements:
Bug fixes:
- fixed back-end enable/disable (priority computing)
------------------------------------------------------------------------
r54 | roseg | 2007-11-29 18:16:36 +0100 (Thu, 29 Nov 2007) | 12 lines
Enhancements:
- added PARM session type. Old PARM is now URL
- allow AddHeader for HTTP listeners as well
- allow -1 for session (all types) TTL. Will hash the key to a fixed value
- Redirect takes an optional code parameter (301, 302/default or 307)
- new config param to allow printing the SSL certificate in a single line
- new config param to control the maximal size of the input line
- added better error messages for SSL loading problems
Bug fixes:
- if the same cookie is defined more than once use LAST definition
------------------------------------------------------------------------
r53 | roseg | 2007-08-15 18:26:58 +0200 (Wed, 15 Aug 2007) | 10 lines
Release 2.4d
Enhancements:
- moved to GPLv3
- now using lh_hash for the session tables
Bug fixes:
- allow case-sensitive matching for URLs
- fixed memory leak in DNS searches
------------------------------------------------------------------------
r52 | roseg | 2007-07-04 15:29:27 +0200 (Wed, 04 Jul 2007) | 10 lines
Release 2.4c
Enhancements:
- added XML output for poundctl
- added more detailed error messages
Bug fixes:
- fixed problems with extra-long lines
- fixed problems with chunked encoding
------------------------------------------------------------------------
r51 | roseg | 2007-05-18 10:35:02 +0200 (Fri, 18 May 2007) | 11 lines
Release 2.4b
Enhancements:
- cleaned resurrection code
- added RR threads scheduling
Bug fixes:
- fixed problem long lines (thanks to Rune Saetre)
- fixed pcreposix autoconf for systems that also require pcre
- fixed problem with IP session handling
------------------------------------------------------------------------
r49 | roseg | 2007-04-30 15:01:17 +0200 (Mon, 30 Apr 2007) | 11 lines
Release 2.4a
Enhancements:
- added display of configuration switches
- added grace period for shutdown (based on an idea from Rune Saetre)
- added support for IPv6 (but host caching was removed)
Bug fixes:
- fixed test for owner/group (BSD portability)
- fixed problem with premature opening of control socket
------------------------------------------------------------------------
r46 | roseg | 2007-04-11 15:00:11 +0200 (Wed, 11 Apr 2007) | 8 lines
Release 2.3
Enhancements:
- added display of configuration switches
- added grace period for shutdown (based on an idea from Rune Saetre)
Bug fixes:
------------------------------------------------------------------------
r45 | roseg | 2007-04-04 18:15:53 +0200 (Wed, 04 Apr 2007) | 8 lines
Release 2.2.8
Enhancements:
- more tweaking of the dynamic rescaling code
- more information in poundctl printout
Bug fixes:
------------------------------------------------------------------------
r44 | roseg | 2007-03-12 18:12:14 +0100 (Mon, 12 Mar 2007) | 8 lines
Release 2.2.7
Enhancements:
- dynamic scaling is now a configuration directive (DynScale)
- added vhost to LogLevel 5
Bug fixes:
------------------------------------------------------------------------
r43 | roseg | 2007-03-02 10:30:01 +0100 (Fri, 02 Mar 2007) | 11 lines
Release 2.2.6
Enhancements:
- added transaction time to LogLevel 5
- added priority display for poundctl
Bug fixes:
- fixed problem when adding session via poundctl
- fixed problem in session dump to poundctl
- fixed problem in kill_be call to t_clean
------------------------------------------------------------------------
r42 | roseg | 2007-02-19 18:19:22 +0100 (Mon, 19 Feb 2007) | 7 lines
Release 2.2.5
Enhancements:
Bug fixes:
- fixed problem with sessions (BACKEND copying)
------------------------------------------------------------------------
r41 | roseg | 2007-02-10 15:26:42 +0100 (Sat, 10 Feb 2007) | 14 lines
Release 2.2.4
Enhancements:
- modular tree library
- consolidated all timed functions into a single thread
- added gethostbyname cache
- added LogLevel 5 - same as 4 but with service name and back-end information (thanks to Joe Gooch for the suggestion)
- added session creation and removal to poundctl
Bug fixes:
- added LOG_NDELAY to openlog()
- accept and immediately close connections to disabled listeners (thanks to Joe Gooch for the suggestion)
- fixed problem with -1 values in poundctl
------------------------------------------------------------------------
r40 | roseg | 2007-01-19 21:29:07 +0100 (Fri, 19 Jan 2007) | 5 lines
Release 2.2.3
Bug fixes:
- fixed problems in bad 2.2 release
------------------------------------------------------------------------
r39 | roseg | 2007-01-15 18:17:48 +0100 (Mon, 15 Jan 2007) | 13 lines
Release 2.2.2
Enhancements:
- changes in the dynamic rescaling
- doubled the session key size (for those people with insanely long cookies)
- added LogFacility - for logging to stdout/stderr
- added optional Service names
Bug fixes:
- fixed bug in multiple HeadRemove matching
- fixed problem with extra large session keys
- fixed problem for OpenBSD accept (blocks all threads)
------------------------------------------------------------------------
r38 | roseg | 2007-01-03 18:25:30 +0100 (Wed, 03 Jan 2007) | 13 lines
Release 2.2.1
Enhancements:
- allow specific Listeners to override the gloabl LogLevel value
- allow a default Client value to be defined at the global level
- allow a default TimeOut value to be defined at the global level
- added compile-time flags for file owner and group
Bug fixes:
- fixed some problems in the installation procedure
- fixed problem in SSL session string
- added protocol check in need_rewrite
------------------------------------------------------------------------
r37 | roseg | 2006-12-16 10:18:38 +0100 (Sat, 16 Dec 2006) | 45 lines
Release 2.2
Enhancements:
- added the host to LogLevel 2 (if available)
- added support for tcmalloc (from the Google perftools package)
Bug fixes:
- fixed problem with the initialisation of host_mut
*****************************
Cumulative changes since 2.1:
*****************************
Enhancements:
- added dynamic rescaling of back-end priorities, compile-time flag to enable/disable it
- added support for emergency back-ends
- the program poundctl(8) is now available, added the Control configuration directive
- SESS_IP now behaves like other session types (no longer sticky)
- added RewriteLocation 2: rewrite location if it points to same address, but ignore port
- Redirect uses the original request path
- added RewriteDestination configuration flag to enable rewriting the Destination header
- removed msdav compile-time configuration flag and MSDAV configuration flag, extended xHTTP to allow for
WebDAV, MS-DAV and MS-RPC
- added CRLlist directive, split CRL from CA
- Error replies are sent as pure HTML
- split error messages into:
- LOG_ERR: errors (mostly fatal)
- LOG_WARNING: errors (non-fatal)
- LOG_NOTICE: problems
- LOG_INFO: extra information
- time to serve the requests is logged in LogLevel 2
- added the (virtual) host to LogLevel 2 (if available)
- added line numbers to config error messages
- added TCP_NODELAY for faster response times
- added support for tcmalloc (from the Google perftools package)
Bug fixes:
- fixed problem in str_be (evident mostly in LogLevel 2)
- added 'const' wherever necessary
- check for errors in mutex handling
- fixed the verb pattern in HTTPS listeners
- content is now ignored only on HEAD requests
- fixed problems with autoconf on some systems
- fixed problem with the initialisation of host_mut
------------------------------------------------------------------------
r36 | roseg | 2006-12-09 09:39:23 +0100 (Sat, 09 Dec 2006) | 6 lines
Release 2.1.8
Bug fixes:
- fixed another small problem with autoconf on some systems
- added support for systems that don't define SOL_TCP
------------------------------------------------------------------------
r35 | roseg | 2006-12-06 18:32:16 +0100 (Wed, 06 Dec 2006) | 10 lines
Release 2.1.7
Enhancements:
- added TCP_NODELAY for faster response times
- added compile-time flag to enable/disable dynamic priorities rescaling
Bug fixes:
- fixed problems with autoconf on some systems
- fixed error in control function (be instead of svc)
------------------------------------------------------------------------
r34 | roseg | 2006-11-04 11:28:53 +0100 (Sat, 04 Nov 2006) | 9 lines
Release 2.1.6
Enhancements:
- Redirect uses the original request path
Bug fixes:
- improved dynamic priorities calculation
- fixed problem with Emergency back-ends
------------------------------------------------------------------------
r33 | roseg | 2006-10-23 09:24:28 +0200 (Mon, 23 Oct 2006) | 12 lines
Release 2.1.5
Enhancements:
- added line numbers to config error messages
- added dynamic rescaling of back-end priorities
- added support for emergency back-ends
- the program poundctl(8) is now available
- added the Control configuration directive
Bug fixes:
- improved owner/group detection for install
------------------------------------------------------------------------
r32 | roseg | 2006-10-14 16:39:29 +0200 (Sat, 14 Oct 2006) | 6 lines
Release 2.1.4
Bug fixes:
- content is now ignored only on HEAD requests
- added CRLlist directive, split CRL from CA
------------------------------------------------------------------------
r31 | roseg | 2006-09-21 18:41:15 +0200 (Thu, 21 Sep 2006) | 6 lines
Release 2.1.3
Bug fixes:
- fixed the verb pattern in HTTPS listeners
- removed the spurious printf in cur_time
------------------------------------------------------------------------
r30 | roseg | 2006-09-18 18:12:16 +0200 (Mon, 18 Sep 2006) | 18 lines
Release 2.1.2
Enhancements:
- Error replies are sent as pure HTML
- split error messages into:
- LOG_ERR: errors (mostly fatal)
- LOG_WARNING: errors (non-fatal)
- LOG_NOTICE: problems
- LOG_INFO: extra information
- removed msdav compile-time configuration flag
- removed MSDAV configuration flag
- extended xHTTP to allow for WebDAV, MS-DAV and MS-RPC
- added RewriteDestination configuration flag to enable rewriting the Destination header
- time to serve the requests is logged in LogLevel 2
Bug fixes:
- fixed (again) the RewriteRedirect 2 mode
------------------------------------------------------------------------
r29 | roseg | 2006-09-11 18:35:22 +0200 (Mon, 11 Sep 2006) | 11 lines
Release 2.1.1
Enhancements:
- SESS_IP now behaves like other session types (no longer sticky)
- added RewriteLocation 2: rewrite location if it points to same address, but ignore port
Bug fixes:
- fixed problem in str_be (evident mostly in LogLevel 2)
- added 'const' wherever necessary
- check for errors in mutex handling
------------------------------------------------------------------------
r27 | roseg | 2006-08-05 11:35:52 +0200 (Sat, 05 Aug 2006) | 24 lines
Release 2.1
Enhancements:
- support for pcre library (if available) for much better performance
- support for hoard library (if available) for much better performance
- rewrite Location and Content-location headers for all responses
- improved detection of when is a rewrite necessary
- renamed Change30x to RewriteLocation. Default: on
Bug fixes:
- fixed small problem in the upd_session() code
- declared init_RSAgen() as void everywhere
- moved to SESS_xxx tokens to avoid Solaris name conflict
- added #ifdef's for LOG_FTP and LOG_AUTHPRIV
- fixed problem in URL checking
- fixed problem in session tracking-code and session updating
- fixed LogLevel 3 to show that the v_host is unknown
- fixed headers checking in match_service
- fixed problem in ClientCert directive handling
- fixed potential memory leak in AUTH decoding
- allow OPTIONS WebDAV request to have content
- replaced inet_ntoa with inet_ntop where available
- removed all static buffers
------------------------------------------------------------------------
r25 | roseg | 2006-02-01 10:00:42 +0100 (Wed, 01 Feb 2006) | 14 lines
Release 2.0
Enhancements:
- new configuration file syntax, offering significant improvements.
- the ability to define listener-specific back-ends. In most cases
this should eliminate the need for multiple Pound instances.
- a new type of back-end: the redirector allows you to respond with
a redirect without involving any back-end server.
- most "secondary" properties (such as error messages, client
time-out, etc.) are now private to listeners.
- HAport has an optional address, different from the main back-end
- added a -V flag for version
- session keeping on a specific Header
------------------------------------------------------------------------
r21 | roseg | 2006-02-01 14:27:19 +0100 (Wed, 01 Feb 2006) | 15 lines
Release 1.10
Enhancements:
added NoDaemon configuration directive (replaces compile-time switch)
added LogFacility configuration directive (replaces compile-time switch)
added user name logging
Bug fixes:
fixed problem with the poll() code
fixed problem with empty list in gethostbyname()
added call to setsid() if daemon
conflicting headers are removed (Content-length - Transfer-encoding)
Last release in the 1.x series.
------------------------------------------------------------------------
r19 | roseg | 2005-06-01 15:27:19 +0200 (Wed, 01 Jun 2005) | 18 lines
Release 1.9
Enhancements:
- Added the VerifyList configuration flag (CA root certs + CRL)
- CRL checking code
- RewriteRedirect 2 - ignores port value for host matching
- Added -c flag (check-only mode)
- Added -v flag (verbose mode)
- Added -p flag for pid file name
Bug fixes:
- fixed a potential buffer overflow problem (in checking the Host header)
- added call to SSL_library_init
- added a check for MSIE before forcing SSL shutdown
- X-SSL-Cipher header is added only if HTTPSHeaders is non-zero
- added code for shorter linger on badly closed connections (IE work-around)
- fixed the locking for session checking (mutex_lock/unlock)
------------------------------------------------------------------------
r17 | roseg | 2004-11-04 14:27:19 +0100 (Thu, 04 Nov 2004) | 23 lines
Release 1.8
Changes:
- added support for non-blocking connect(2)
- added support for 414 - Request URI too long
- added RedirectRewrite directive - to prevent redirect changes
- added support for NoHTTPS11 value 2 (for MSIE clients only)
- added support for HTTPSHeaders 3 (no verify)
Problems fixed:
- fixed bug if multiple listening ports/addresses
- fixed memory leak in SSL
- flush stdout (if used) after each log message
- assumes only 304, 305 and 306 codes to have no content
- fixed problem with delays in 302 without content
- fixed problem with time-outs in HTTPS
Enhancements:
- improved threads detection code in autoconf
- added supervisor process disable configuration flag
- tweak for the Location rewriting code (only look at current GROUP)
- improved print-out for client certificate information
------------------------------------------------------------------------
r15 | roseg | 2004-03-24 14:27:19 +0100 (Wed, 24 Mar 2004) | 12 lines
Release 1.7
Fixed bug in X-SSL-CIPHER description
Changed README to stx format for consistency
Addedd X-SSL-certificate with full client certificate
Improved the response times on HTTP/0.9 (content without Content-length)
Improved response granularity on above - using unbuffered BIO now
Fixed problem with IE/SSL (SSL_set_shutdown)
Avoid error messages on premature EOF from client
Fixed HeadRemove code so all headers are checked without exception
Improved autoconf detection
------------------------------------------------------------------------
r13 | roseg | 2003-11-30 14:27:19 +0100 (Sun, 30 Nov 2003) | 15 lines
Release 1.6
Callback for RSA ephemeral keys:
- generated in a separate thread
- used if required (IE 5.0?)
New X-SSL-cipher header encryption level/method
Added CheckURL parameter in config file
- perform syntax check only if value 1 (default 0)
Allow for empty query/param strings in URL syntax
Additional SSL engine loading code
Added parameter for CA certificates
- CA list is sent to client
Verify client certificates up to given depth
Fixed vulnerability in syslog handling
------------------------------------------------------------------------
r11 | roseg | 2003-10-14 15:27:19 +0200 (Tue, 14 Oct 2003) | 19 lines
Release 1.5
Session by Basic Authentication:
Session BASIC parameter added
Syntax checking of request.
User-defined request character set(s):
Parameters CSsegment, CSparameter, CSqid, CSqval
Request size limit:
Parameter MaxRequest
Single log function rather than #ifdefs.
Added LogLevel 4 (same as 3 but without the virtual host info).
Added HeadRemove directive (allows to delete a header from requests).
Location rewriting on redirect:
if the request contains a Header directive
and the response is codes 301, 302, 303, 307
and the Location in the response is to a known host
then the Location header in the response will be rewritten to point
to the Pound protocol/port itself
------------------------------------------------------------------------
r9 | roseg | 2003-04-24 15:27:19 +0200 (Thu, 24 Apr 2003) | 12 lines
Release 1.4
Added 'Server' configuration directive
Fixed problem with HTTPSHeaders 0 "..." - the desired header is written even if HTTPSHeaders is 0
Added the ability of loading a certificate chain.
Added compatability with OpenSSL 0.9.7
Added user-definable error pages.
Added compile-time flags to run in foreground and to log to stderr.
Opens separate pid files per-process.
Improved autoconf.
Some SSL speed optimisations.
------------------------------------------------------------------------
r7 | roseg | 2003-02-19 14:27:19 +0100 (Wed, 19 Feb 2003) | 10 lines
Release 1.3
Added support for OpenSSL Engine (crypto hardware)
Added support for Subversion WebDAV
Added support for mandatory client certificates
Added X-SSL-serial header for SSL connections
Fixed problem with BIO_pending in is_readable
Fixed problem with multi-threading in OpenSSL
Improved autoconf
------------------------------------------------------------------------
r5 | roseg | 2003-01-20 14:27:19 +0100 (Mon, 20 Jan 2003) | 5 lines
Release 1.2
Better handling of "100 Continue" responses
Fixed problem with allowed character set for requests
------------------------------------------------------------------------
r3 | roseg | 2003-01-09 14:27:19 +0100 (Thu, 09 Jan 2003) | 9 lines
Better auto-conf detection
LogLevel 3 for Apache-like log (Combined Log Format)
Don't ask client for certificate if no SSL headers required
Added handling for 'Connection: closed' header
Added monitor process to restart worker process if crashed
Added possibility to listen on all interfaces
Fixed HeadDeny code
Fixed problem with threads on *BSD
------------------------------------------------------------------------
r1 | roseg | 2002-10-31 14:27:19 +0100 (Thu, 31 Oct 2002) | 1 line
Initial import
------------------------------------------------------------------------
Pound-2.8/poundctl.c 0000755 0001750 0001750 00000027471 13275266545 013521 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#define NO_EXTERNALS 1
#include "pound.h"
static int xml_out = 0;
static int host_names = 0;
static void
usage(const char *arg0)
{
fprintf(stderr, "Usage: %s -c /control/socket [ -X ] cmd\n", arg0);
fprintf(stderr, "\twhere cmd is one of:\n");
fprintf(stderr, "\t-L n - enable listener n\n");
fprintf(stderr, "\t-l n - disable listener n\n");
fprintf(stderr, "\t-S n m - enable service m in service n (use -1 for global services)\n");
fprintf(stderr, "\t-s n m - disable service m in service n (use -1 for global services)\n");
fprintf(stderr, "\t-B n m r - enable back-end r in service m in listener n\n");
fprintf(stderr, "\t-b n m r - disable back-end r in service m in listener n\n");
fprintf(stderr, "\t-N n m k r - add a session with key k and back-end r in service m in listener n\n");
fprintf(stderr, "\t-n n m k - remove a session with key k r in service m in listener n\n");
fprintf(stderr, "\n");
fprintf(stderr, "\tentering the command without arguments lists the current configuration.\n");
fprintf(stderr, "\tthe -X flag results in XML output.\n");
fprintf(stderr, "\tthe -H flag shows symbolic host names instead of addresses.\n");
exit(1);
}
/*
* Translate inet/inet6 address/port into a string
*/
static char *
prt_addr(const struct addrinfo *addr)
{
static char res[UNIX_PATH_MAX];
char buf[UNIX_PATH_MAX];
int port;
void *src;
memset(buf, 0, UNIX_PATH_MAX);
#ifdef HAVE_INET_NTOP
switch(addr->ai_family) {
case AF_INET:
src = (void *)&((struct sockaddr_in *)addr->ai_addr)->sin_addr.s_addr;
port = ntohs(((struct sockaddr_in *)addr->ai_addr)->sin_port);
if(host_names && !getnameinfo(addr->ai_addr, addr->ai_addrlen, buf, UNIX_PATH_MAX - 1, NULL, 0, 0))
break;
if(inet_ntop(AF_INET, src, buf, UNIX_PATH_MAX - 1) == NULL)
strncpy(buf, "(UNKNOWN)", UNIX_PATH_MAX - 1);
break;
case AF_INET6:
src = (void *)&((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr.s6_addr;
port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
if(host_names && !getnameinfo(addr->ai_addr, addr->ai_addrlen, buf, UNIX_PATH_MAX - 1, NULL, 0, 0))
break;
if(inet_ntop(AF_INET6, src, buf, UNIX_PATH_MAX - 1) == NULL)
strncpy(buf, "(UNKNOWN)", UNIX_PATH_MAX - 1);
break;
case AF_UNIX:
strncpy(buf, (char *)addr->ai_addr, UNIX_PATH_MAX - 1);
port = 0;
break;
default:
strncpy(buf, "(UNKNOWN)", UNIX_PATH_MAX - 1);
port = 0;
break;
}
snprintf(res, UNIX_PATH_MAX - 1, "%s:%d", buf, port);
#else
#error "Pound needs inet_ntop()"
#endif
return res;
}
static void
be_prt(const int sock)
{
BACKEND be;
struct sockaddr_storage a, h;
int n_be;
n_be = 0;
while(read(sock, (void *)&be, sizeof(BACKEND)) == sizeof(BACKEND)) {
if(be.disabled < 0)
break;
read(sock, &a, be.addr.ai_addrlen);
be.addr.ai_addr = (struct sockaddr *)&a;
if(be.ha_addr.ai_addrlen > 0) {
read(sock, &h, be.ha_addr.ai_addrlen);
be.ha_addr.ai_addr = (struct sockaddr *)&h;
}
if(xml_out)
printf("\n",
n_be++,
prt_addr(&be.addr), be.t_average / 1000000, be.priority, be.alive? "yes": "DEAD",
be.disabled? "DISABLED": "active");
else
printf(" %3d. Backend %s %s (%d %.3f sec) %s\n", n_be++, prt_addr(&be.addr),
be.disabled? "DISABLED": "active", be.priority, be.t_average / 1000000, be.alive? "alive": "DEAD");
}
return;
}
static void
sess_prt(const int sock)
{
TABNODE sess;
int n_be, n_sess, cont_len;
char buf[KEY_SIZE + 1], escaped[KEY_SIZE * 2 + 1];
n_sess = 0;
while(read(sock, (void *)&sess, sizeof(TABNODE)) == sizeof(TABNODE)) {
if(sess.content == NULL)
break;
read(sock, &n_be, sizeof(n_be));
read(sock, &cont_len, sizeof(cont_len));
memset(buf, 0, KEY_SIZE + 1);
/* cont_len is at most KEY_SIZE */
read(sock, buf, cont_len);
if(xml_out) {
int i, j;
char escaped[KEY_SIZE * 2 + 1];
for(i = j = 0; buf[i]; i++)
if(buf[i] == '"') {
escaped[j++] = '\\';
escaped[j++] = '"';
} else
escaped[j++] = buf[i];
escaped[j] = '\0';
printf("\n", n_sess++, escaped, n_be);
} else
printf(" %3d. Session %s -> %d\n", n_sess++, buf, n_be);
}
return;
}
static void
svc_prt(const int sock)
{
SERVICE svc;
int n_svc;
n_svc = 0;
while(read(sock, (void *)&svc, sizeof(SERVICE)) == sizeof(SERVICE)) {
if(svc.disabled < 0)
break;
if(xml_out) {
if(svc.name[0])
printf("\n",
n_svc++, svc.name, svc.disabled? "DISABLED": "active");
else
printf("\n", n_svc++, svc.disabled? " DISABLED": "");
} else {
if(svc.name[0])
printf(" %3d. Service \"%s\" %s (%d)\n", n_svc++, svc.name, svc.disabled? "DISABLED": "active",
svc.tot_pri);
else
printf(" %3d. Service %s (%d)\n", n_svc++, svc.disabled? "DISABLED": "active", svc.tot_pri);
}
be_prt(sock);
sess_prt(sock);
if(xml_out)
printf("\n");
}
return;
}
static int
get_sock(const char *sock_name)
{
struct sockaddr_un ctrl;
int res;
memset(&ctrl, 0, sizeof(ctrl));
ctrl.sun_family = AF_UNIX;
strncpy(ctrl.sun_path, sock_name, sizeof(ctrl.sun_path) - 1);
if((res = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
perror("socket create");
exit(1);
}
if(connect(res, (struct sockaddr *)&ctrl, (socklen_t)sizeof(ctrl)) < 0) {
perror("connect");
exit(1);
}
return res;
}
int
main(const int argc, char **argv)
{
CTRL_CMD cmd;
int sock, n_lstn, n_svc, n_be, n_sess, i;
char *arg0, *sock_name, buf[KEY_SIZE + 1];
int c_opt, en_lst, de_lst, en_svc, de_svc, en_be, de_be, a_sess, d_sess, is_set;
LISTENER lstn;
SERVICE svc;
BACKEND be;
TABNODE sess;
struct sockaddr_storage a;
arg0 = *argv;
sock_name = NULL;
en_lst = de_lst = en_svc = de_svc = en_be = de_be = is_set = a_sess = d_sess = 0;
memset(&cmd, 0, sizeof(cmd));
opterr = 0;
i = 0;
while(!i && (c_opt = getopt(argc, argv, "c:LlSsBbNnXH")) > 0)
switch(c_opt) {
case 'c':
sock_name = optarg;
break;
case 'X':
xml_out = 1;
break;
case 'L':
if(is_set)
usage(arg0);
en_lst = is_set = 1;
break;
case 'l':
if(is_set)
usage(arg0);
de_lst = is_set = 1;
break;
case 'S':
if(is_set)
usage(arg0);
en_svc = is_set = 1;
break;
case 's':
if(is_set)
usage(arg0);
de_svc = is_set = 1;
break;
case 'B':
if(is_set)
usage(arg0);
en_be = is_set = 1;
break;
case 'b':
if(is_set)
usage(arg0);
de_be = is_set = 1;
break;
case 'N':
if(is_set)
usage(arg0);
a_sess = is_set = 1;
break;
case 'n':
if(is_set)
usage(arg0);
d_sess = is_set = 1;
break;
case 'H':
host_names = 1;
break;
default:
if(optopt == '1') {
optind--;
i = 1;
} else {
fprintf(stderr, "bad flag -%c", optopt);
usage(arg0);
}
break;
}
if(sock_name == NULL)
usage(arg0);
if(en_lst || de_lst) {
if(optind != (argc - 1))
usage(arg0);
cmd.cmd = (en_lst? CTRL_EN_LSTN: CTRL_DE_LSTN);
cmd.listener = atoi(argv[optind++]);
}
if(en_svc || de_svc) {
if(optind != (argc - 2))
usage(arg0);
cmd.cmd = (en_svc? CTRL_EN_SVC: CTRL_DE_SVC);
cmd.listener = atoi(argv[optind++]);
cmd.service = atoi(argv[optind++]);
}
if(en_be || de_be) {
if(optind != (argc - 3))
usage(arg0);
cmd.cmd = (en_be? CTRL_EN_BE: CTRL_DE_BE);
cmd.listener = atoi(argv[optind++]);
cmd.service = atoi(argv[optind++]);
cmd.backend = atoi(argv[optind++]);
}
if(a_sess) {
if(optind != (argc - 4))
usage(arg0);
cmd.cmd = CTRL_ADD_SESS;
cmd.listener = atoi(argv[optind++]);
cmd.service = atoi(argv[optind++]);
memset(cmd.key, 0, KEY_SIZE + 1);
strncpy(cmd.key, argv[optind++], KEY_SIZE);
cmd.backend = atoi(argv[optind++]);
}
if(d_sess) {
if(optind != (argc - 3))
usage(arg0);
cmd.cmd = CTRL_DEL_SESS;
cmd.listener = atoi(argv[optind++]);
cmd.service = atoi(argv[optind++]);
strncpy(cmd.key, argv[optind++], KEY_SIZE);
}
if(!is_set) {
if(optind != argc)
usage(arg0);
cmd.cmd = CTRL_LST;
}
sock = get_sock(sock_name);
write(sock, &cmd, sizeof(cmd));
if (!is_set) {
int n;
n_lstn = 0;
if(xml_out)
printf("\n");
if(read(sock, &n, sizeof(n)) == sizeof(n))
if(xml_out)
printf("\n", n);
else
printf("Requests in queue: %d\n", n);
while(read(sock, (void *)&lstn, sizeof(LISTENER)) == sizeof(LISTENER)) {
if(lstn.disabled < 0)
break;
read(sock, &a, lstn.addr.ai_addrlen);
lstn.addr.ai_addr = (struct sockaddr *)&a;
if(xml_out)
printf("\n",
n_lstn++, lstn.ctx? "HTTPS": "http",
prt_addr(&lstn.addr), lstn.disabled? "DISABLED": "active");
else
printf("%3d. %s Listener %s %s\n", n_lstn++, lstn.ctx? "HTTPS" : "http",
prt_addr(&lstn.addr), lstn.disabled? "*D": "a");
svc_prt(sock);
if(xml_out)
printf("\n");
}
if(!xml_out)
printf(" -1. Global services\n");
svc_prt(sock);
if(xml_out)
printf("\n");
}
return 0;
}
Pound-2.8/pound.h 0000644 0001750 0001750 00000037644 13275266545 013023 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#include "config.h"
#include
#include
#if HAVE_STDLIB_H
#include
#else
#error "Pound needs stdlib.h"
#endif
#if HAVE_UNISTD_H
#include
#else
#error "Pound needs unistd.h"
#endif
#if HAVE_GETOPT_H
#include
#endif
#if HAVE_PTHREAD_H
#include
#else
#error "Pound needs pthread.h"
#endif
#if HAVE_STRING_H
#include
#else
#error "Pound needs string.h"
#endif
#if TIME_WITH_SYS_TIME
#if HAVE_SYS_TIME_H
#include
#else
#error "Pound needs sys/time.h"
#endif
#if HAVE_TIME_H
#include
#else
#error "Pound needs time.h"
#endif
#else /* may not mix sys/time.h and time.h */
#if HAVE_SYS_TIME_H
#include
#elif HAVE_TIME_H
#include
#else
#error "Pound needs time.h"
#endif
#endif /* mix */
#if HAVE_SYS_TYPES_H
#include
#else
#error "Pound needs sys/types.h"
#endif
#if HAVE_SYS_SOCKET_H
#include
#else
#error "Pound needs sys/socket.h"
#endif
#if HAVE_SYS_UN_H
#include
#else
#error "Pound needs sys/un.h"
#endif
#ifndef UNIX_PATH_MAX
/* on Linux this is defined in linux/un.h rather than sys/un.h - go figure */
#define UNIX_PATH_MAX 108
#endif
#if HAVE_NETINET_IN_H
#include
#else
#error "Pound needs netinet/in.h"
#endif
#if HAVE_NETINET_TCP_H
#include
#else
#error "Pound needs netinet/tcp.h"
#endif
#if HAVE_ARPA_INET_H
#include
#else
#error "Pound needs arpa/inet.h"
#endif
#if HAVE_NETDB_H
#include
#else
#error "Pound needs netdb.h"
#endif
#if HAVE_SYS_POLL_H
#include
#else
#error "Pound needs sys/poll.h"
#endif
#if HAVE_OPENSSL_SSL_H
#define OPENSSL_THREAD_DEFINES
#include
#include
#include
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
#ifndef OPENSSL_THREADS
#error "Pound requires OpenSSL with thread support"
#endif
#else
#ifndef THREADS
#error "Pound requires OpenSSL with thread support"
#endif
#endif
#else
#error "Pound needs openssl/ssl.h"
#endif
#if HAVE_OPENSSL_ENGINE_H
#include
#endif
#if HAVE_PWD_H
#include
#else
#error "Pound needs pwd.h"
#endif
#if HAVE_GRP_H
#include
#else
#error "Pound needs grp.h"
#endif
#if HAVE_SYSLOG_H
#include
#endif
#if HAVE_SYS_SYSLOG_H
#include
#endif
#if HAVE_SIGNAL_H
#include
#else
#error "Pound needs signal.h"
#endif
#if HAVE_LIBPCREPOSIX
#if HAVE_PCREPOSIX_H
#include
#elif HAVE_PCRE_PCREPOSIX_H
#include
#else
#error "You have libpcreposix, but the header files are missing. Use --disable-pcreposix"
#endif
#elif HAVE_REGEX_H
#include
#else
#error "Pound needs regex.h"
#endif
#if HAVE_CTYPE_H
#include
#else
#error "Pound needs ctype.h"
#endif
#if HAVE_ERRNO_H
#include
#else
#error "Pound needs errno.h"
#endif
#if HAVE_WAIT_H
#include
#elif HAVE_SYS_WAIT_H
#include
#else
#error "Pound needs sys/wait.h"
#endif
#if HAVE_SYS_STAT_H
#include
#else
#error "Pound needs sys/stat.h"
#endif
#if HAVE_FCNTL_H
#include
#else
#error "Pound needs fcntl.h"
#endif
#if HAVE_STDARG_H
#include
#else
#include
#endif
#if HAVE_FNMATCH_H
#include
#else
#error "Pound needs fnmatch.h"
#endif
#ifndef __STDC__
#define const
#endif
#ifdef HAVE_LONG_LONG_INT
#define LONG long long
#define L0 0LL
#define L_1 -1LL
#define STRTOL strtoll
#define ATOL atoll
#else
#define LONG long
#define L0 0L
#define L_1 -1L
#define STRTOL strtol
#define ATOL atol
#endif
#ifndef NO_EXTERNALS
/*
* Global variables needed by everybody
*/
extern char *user, /* user to run as */
*group, /* group to run as */
*root_jail, /* directory to chroot to */
*pid_name, /* file to record pid in */
*ctrl_name; /* control socket name */
extern int numthreads, /* number of worker threads */
anonymise, /* anonymise client address */
alive_to, /* check interval for resurrection */
daemonize, /* run as daemon */
log_facility, /* log facility to use */
print_log, /* print log messages to stdout/stderr */
grace, /* grace period before shutdown */
control_sock; /* control socket */
extern regex_t HEADER, /* Allowed header */
CHUNK_HEAD, /* chunk header line */
RESP_SKIP, /* responses for which we skip response */
RESP_IGN, /* responses for which we ignore content */
LOCATION, /* the host we are redirected to */
AUTHORIZATION; /* the Authorisation header */
#ifndef SOL_TCP
/* for systems without the definition */
extern int SOL_TCP;
#endif
#endif /* NO_EXTERNALS */
#ifndef MAXBUF
#define MAXBUF 4096
#endif
#define MAXHEADERS 128
#ifndef F_CONF
#define F_CONF "/usr/local/etc/pound.cfg"
#endif
#ifndef F_PID
#define F_PID "/var/run/pound.pid"
#endif
/* matcher chain */
typedef struct _matcher {
regex_t pat; /* pattern to match the request/header against */
struct _matcher *next;
} MATCHER;
/* back-end types */
typedef enum { SESS_NONE, SESS_IP, SESS_COOKIE, SESS_URL, SESS_PARM, SESS_HEADER, SESS_BASIC } SESS_TYPE;
/* back-end definition */
typedef struct _backend {
int be_type; /* 0 if real back-end, otherwise code (301, 302/default, 307) */
struct addrinfo addr; /* IPv4/6 address */
int priority; /* priority */
int to; /* read/write time-out */
int conn_to; /* connection time-out */
struct addrinfo ha_addr; /* HA address/port */
char *url; /* for redirectors */
int redir_req; /* the redirect should include the request path */
SSL_CTX *ctx; /* CTX for SSL connections */
pthread_mutex_t mut; /* mutex for this back-end */
int n_requests; /* number of requests seen */
double t_requests; /* time to answer these requests */
double t_average; /* average time to answer requests */
int alive; /* false if the back-end is dead */
int resurrect; /* this back-end is to be resurrected */
int disabled; /* true if the back-end is disabled */
struct _backend *next;
} BACKEND;
typedef struct _tn {
char *key;
void *content;
time_t last_acc;
} TABNODE;
#define n_children(N) ((N)? (N)->children: 0)
/* maximal session key size */
#define KEY_SIZE 127
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
DECLARE_LHASH_OF(TABNODE);
#endif
/* service definition */
typedef struct _service {
char name[KEY_SIZE + 1]; /* symbolic name */
MATCHER *url, /* request matcher */
*req_head, /* required headers */
*deny_head; /* forbidden headers */
BACKEND *backends;
BACKEND *emergency;
int abs_pri; /* abs total priority for all back-ends */
int tot_pri; /* total priority for current back-ends */
pthread_mutex_t mut; /* mutex for this service */
SESS_TYPE sess_type;
int sess_ttl; /* session time-to-live */
regex_t sess_start; /* pattern to identify the session data */
regex_t sess_pat; /* pattern to match the session data */
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
LHASH_OF(TABNODE) *sessions; /* currently active sessions */
#else
LHASH *sessions; /* currently active sessions */
#endif
int disabled; /* true if the service is disabled */
struct _service *next;
} SERVICE;
#ifndef NO_EXTERNALS
extern SERVICE *services; /* global services (if any) */
#endif /* NO_EXTERNALS */
typedef struct _pound_ctx {
SSL_CTX *ctx;
char *server_name;
unsigned char **subjectAltNames;
unsigned int subjectAltNameCount;
struct _pound_ctx *next;
} POUND_CTX;
/* Listener definition */
typedef struct _listener {
struct addrinfo addr; /* IPv4/6 address */
int sock; /* listening socket */
POUND_CTX *ctx; /* CTX for SSL connections */
int clnt_check; /* client verification mode */
int noHTTPS11; /* HTTP 1.1 mode for SSL */
char *add_head; /* extra SSL header */
regex_t verb; /* pattern to match the request verb against */
int to; /* client time-out */
int has_pat; /* was a URL pattern defined? */
regex_t url_pat; /* pattern to match the request URL against */
char *err414, /* error messages */
*err500,
*err501,
*err503;
LONG max_req; /* max. request size */
MATCHER *head_off; /* headers to remove */
int rewr_loc; /* rewrite location response */
int rewr_dest; /* rewrite destination header */
int disabled; /* true if the listener is disabled */
int log_level; /* log level for this listener */
int allow_client_reneg; /* Allow Client SSL Renegotiation */
int disable_ssl_v2; /* Disable SSL version 2 */
SERVICE *services;
struct _listener *next;
} LISTENER;
#ifndef NO_EXTERNALS
extern LISTENER *listeners; /* all available listeners */
#endif /* NO_EXTERNALS */
typedef struct _thr_arg {
int sock;
LISTENER *lstn;
struct addrinfo from_host;
struct _thr_arg *next;
} thr_arg; /* argument to processing threads: socket, origin */
/* Track SSL handshare/renegotiation so we can reject client-renegotiations. */
typedef enum { RENEG_INIT=0, RENEG_REJECT, RENEG_ALLOW, RENEG_ABORT } RENEG_STATE;
/* Header types */
#define HEADER_ILLEGAL -1
#define HEADER_OTHER 0
#define HEADER_TRANSFER_ENCODING 1
#define HEADER_CONTENT_LENGTH 2
#define HEADER_CONNECTION 3
#define HEADER_LOCATION 4
#define HEADER_CONTLOCATION 5
#define HEADER_HOST 6
#define HEADER_REFERER 7
#define HEADER_USER_AGENT 8
#define HEADER_URI 9
#define HEADER_DESTINATION 10
#define HEADER_EXPECT 11
/* control request stuff */
typedef enum {
CTRL_LST,
CTRL_EN_LSTN, CTRL_DE_LSTN,
CTRL_EN_SVC, CTRL_DE_SVC,
CTRL_EN_BE, CTRL_DE_BE,
CTRL_ADD_SESS, CTRL_DEL_SESS
} CTRL_CODE;
typedef struct {
CTRL_CODE cmd;
int listener;
int service;
int backend;
char key[KEY_SIZE + 1];
} CTRL_CMD;
#ifdef NEED_INADDRT
/* for oldish Unices - normally this is in /usr/include/netinet/in.h */
typedef u_int32_t in_addr_t;
#endif
#ifdef NEED_INPORTT
/* for oldish Unices - normally this is in /usr/include/netinet/in.h */
typedef u_int16_t in_port_t;
#endif
#ifdef NEED_TIMET
/* for oldish Unices - normally this is in /usr/include/time.h */
typedef u_int32_t time_t;
#endif
/*
* add a request to the queue
*/
extern int put_thr_arg(thr_arg *);
/*
* get a request from the queue
*/
extern thr_arg *get_thr_arg(void);
/*
* get the current queue length
*/
extern int get_thr_qlen(void);
/*
* handle an HTTP request
*/
extern void *thr_http(void *);
/*
* Log an error to the syslog or to stderr
*/
extern void logmsg(const int, const char *, ...);
/*
* Parse a URL, possibly decoding hexadecimal-encoded characters
*/
extern int cpURL(char *, char *, int);
/*
* Translate inet/inet6 address into a string
*/
extern void addr2str(char *, const int, const struct addrinfo *, const int);
/*
* Return a string representation for a back-end address
*/
#define str_be(BUF, LEN, BE) addr2str((BUF), (LEN), &(BE)->addr, 0)
/*
* Find the right service for a request
*/
extern SERVICE *get_service(const LISTENER *, const char *, char **const);
/*
* Find the right back-end for a request
*/
extern BACKEND *get_backend(SERVICE *const, const struct addrinfo *, const char *, char **const);
/*
* Search for a host name, return the addrinfo for it
*/
extern int get_host(char *const, struct addrinfo *, int);
/*
* Find if a redirect needs rewriting
* In general we have two possibilities that require it:
* (1) if the redirect was done to the correct location with the wrong protocol
* (2) if the redirect was done to the back-end rather than the listener
*/
extern int need_rewrite(const int, char *const, char *const, const char *, const LISTENER *, const BACKEND *);
/*
* (for cookies only) possibly create session based on response headers
*/
extern void upd_session(SERVICE *const, char **const, BACKEND *const);
/*
* Parse a header
*/
extern int check_header(const char *, char *);
#define BE_DISABLE -1
#define BE_KILL 1
#define BE_ENABLE 0
/*
* mark a backend host as dead;
* do nothing if no resurection code is active
*/
extern void kill_be(SERVICE *const, const BACKEND *, const int);
/*
* Update the number of requests and time to answer for a given back-end
*/
extern void upd_be(SERVICE *const svc, BACKEND *const be, const double);
/*
* Non-blocking version of connect(2). Does the same as connect(2) but
* ensures it will time-out after a much shorter time period CONN_TO.
*/
extern int connect_nb(const int, const struct addrinfo *, const int);
/*
* Parse arguments/config file
*/
extern void config_parse(const int, char **const);
/*
* RSA ephemeral keys: how many and how often
*/
#define N_RSA_KEYS 11
#ifndef T_RSA_KEYS
#define T_RSA_KEYS 7200
#endif
/*
* return a pre-generated RSA key
*/
extern RSA *RSA_tmp_callback(SSL *, int, int);
/*
* return a pre-generated RSA key
*/
extern DH *DH_tmp_callback(SSL *, int, int);
/*
* Renegotiation callback
*/
extern void SSLINFO_callback(const SSL *s, int where, int rc);
/*
* expiration stuff
*/
#ifndef EXPIRE_TO
#define EXPIRE_TO 60
#endif
#ifndef HOST_TO
#define HOST_TO 300
#endif
/*
* initialise the timer functions:
* - host_mut
* - RSA_mut and keys
*/
extern void init_timer(void);
/*
* run timed functions:
* - RSAgen every T_RSA_KEYS seconds
* - resurrect every alive_to seconds
* - expire every EXPIRE_TO seconds
*/
extern void *thr_timer(void *);
/*
* The controlling thread
* listens to client requests and calls the appropriate functions
*/
extern void *thr_control(void *);
Pound-2.8/config.h.in 0000755 0001750 0001750 00000015251 13275266545 013541 0 ustar roseg roseg /* config.h.in. Generated from configure.in by autoheader. */
/* Define to 1 if you have the header file. */
#undef HAVE_ARPA_INET_H
/* Define to 1 if you have the header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the header file. */
#undef HAVE_ERRNO_H
/* Define to 1 if you have the header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `long long' type. */
#undef HAVE_LONG_LONG_INT
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `getaddrinfo' function. */
#undef HAVE_GETADDRINFO
/* Define to 1 if you have the header file. */
#undef HAVE_GETOPT_H
/* Define to 1 if you have the `gettimeofday' function. */
#undef HAVE_GETTIMEOFDAY
/* Define to 1 if you have the header file. */
#undef HAVE_GRP_H
/* Define to 1 if you have the `inet_ntop' function. */
#undef HAVE_INET_NTOP
/* Define to 1 if you have the header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `dl' library (-ldl). */
#undef HAVE_LIBDL
/* Define if libpcreposix is available */
#undef HAVE_LIBPCREPOSIX
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
/* Define to 1 if you have the header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the header file. */
#undef HAVE_NETDB_H
/* Define to 1 if you have the header file. */
#undef HAVE_NETINET_IN_H
/* Define to 1 if you have the header file. */
#undef HAVE_NETINET_TCP_H
/* Define to 1 if you have the header file. */
#undef HAVE_OPENSSL_ENGINE_H
/* Define to 1 if you have the header file. */
#undef HAVE_OPENSSL_SSL_H
/* Define to 1 if you have the header file. */
#undef HAVE_PCREPOSIX_H
/* Define to 1 if you have the header file. */
#undef HAVE_PCRE_PCREPOSIX_H
/* Define to 1 if you have the `poll' function. */
#undef HAVE_POLL
/* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD
/* Define to 1 if you have the header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the header file. */
#undef HAVE_PWD_H
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the header file. */
#undef HAVE_REGEX_H
/* Define to 1 if you have the `setsid' function. */
#undef HAVE_SETSID
/* Define to 1 if you have the header file. */
#undef HAVE_SIGNAL_H
/* Define to 1 if you have the `socket' function. */
#undef HAVE_SOCKET
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
/* Define to 1 if you have the header file. */
#undef HAVE_STDARG_H
/* Define to 1 if you have the header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `strspn' function. */
#undef HAVE_STRSPN
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_POLL_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_SELECT_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_SOCKET_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TIME_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_UN_H
/* Define to 1 if you have the header file. */
#undef HAVE_SYS_WAIT_H
/* Define to 1 if you have the header file. */
#undef HAVE_TIME_H
/* Define to 1 if you have the header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
/* Define to 1 if you have the header file. */
#undef HAVE_VFORK_H
/* Define to 1 if you have the header file. */
#undef HAVE_WAIT_H
/* Define to 1 if `fork' works. */
#undef HAVE_WORKING_FORK
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if you have the `X509_STORE_set_flags' function. */
#undef HAVE_X509_STORE_SET_FLAGS
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to the necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* Define to the type of arg 1 for `select'. */
#undef SELECT_TYPE_ARG1
/* Define to the type of args 2, 3 and 4 for `select'. */
#undef SELECT_TYPE_ARG234
/* Define to the type of arg 5 for `select'. */
#undef SELECT_TYPE_ARG5
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if you can safely include both and . */
#undef TIME_WITH_SYS_TIME
/* Define to 1 if you have the header file. */
#undef HAVE_FNMATCH_H
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if doesn't define. */
#undef gid_t
/* Define to rpl_malloc if the replacement function should be used. */
#undef malloc
/* Define to `int' if does not define. */
#undef pid_t
/* Define to `int' if doesn't define. */
#undef uid_t
/* Define as `fork' if `vfork' does not work. */
#undef vfork
Pound-2.8/FAQ 0000755 0001750 0001750 00000035011 13275266545 012044 0 ustar roseg roseg FREQUENTLY ASKED QUESTIONS
1. General
==========
1.1 Will Pound run my Web application?
No. Pound is a proxy, not a Web server - it does not deliver content by
itself. It is just the middle-man between a client and a server.
1.2 Will Pound make my server go faster?
No. Pound is just a proxy - no caching of any kind takes place. Pound
IS able to distribute requests between several back-end servers, thus
allowing for faster overall response times, but it won't speed-up a
single Web sever.
1.3 Will Pound make my server more secure?
Probably yes. Pound has its own checks on the validity of HTTP requests
and often catches malicious requests that are used to attack Web servers.
1.4 Can I use Pound to change/rewrite/redirect requests?
No. Pound tries to be as transparent as possible - ideally a client
should not be aware that there is anything between itself and the actual
Web server. A limited form of redirect is available - see the man page.
1.5 Can I use Pound to deny certain requests?
Yes. Pound has a rather good mechanism for classifying requests and it
can deny/reject certain requests based on URL and/or header content.
2. Configuration, Compilation and Installation
==============================================
2.1 I try to compile and it fails on "needs OpenSSL with thread support"
Pound is a multi-threaded program and it needs an OpenSSL library
compiled with thread support (optional in the OpenSSL configuration and
absent in some default installations, such as *BSD). If your default
library does not support threads you must install a thread-enabled
version.
2.2 Pound compiles correctly but crashes on *BSD
On some of the newer versions of *BSD (FreeBSD 5.x, OpenBSD 3.x) the
Pound autoconf may not correctly recognize the threading library. Add
manually to the generated Makefile the option -DNEED_STACK in the
CFLAGS.
2.3 I want to run Pound with daemon-tools but it goes to background
You need to configure Pound for non-daemon operations: add "Daemon 0"
to the config file.
2.4 Pound runs OK but some normal requests are rejected with "bad URL"
Pound checks the requested URLs quite thoroughly and rejects malformed
or illegal URLs - or at least illegal according to the RFCs. See the
man page for details.
2.5 Pound runs OK but I get a "pthread_create" error message
You may be hitting the system limit on the number of processes. On
systems that implement threads as processes (as Linux does) you should
make sure that the Pound process has permission to start a sufficient
number of processes.
In some rare cases you may be running into the system limit on the
number of threads. Check your system details for the value of
PTHREAD_THREADS_MAX. If needed you must recompile the threads library
with a higher value.
2.6 What resources does Pound need/use?
That depends very much on your system. On some systems, such as Linux
and System V (AIX, HP-UX, etc), threads are implemented as processes,
which means you must allow enough processes to run. On other systems,
such as *BSD, where threads are implemented in user space (in-process),
you should make sure that Pound can use sufficient memory for all the
threads and that the process is allowed to use enough file descriptors
(2 per active connection). Finally, on systems that implement threads
natively, such as Solaris, you need to make sure that enough threads
and open file descriptors are allowed.
2.7 Is NPTL supported?
Theoretically Pound will work with any POSIX-compliant threads package.
In practice some of the newer NPTL implementations still have some
bugs. At least on Linux running Pound with LD_ASSUME_KERNEL=2.4.19
may be helpful.
3. Virtual Hosts
================
3.1 How do I redirect specific virtual hosts to specific back-ends?
Make the virtual host mandatory in the UrlGroup. For example, to have
all requests to www.a.com go to 192.168.0.10 and all requests for
www.b.com go to 192.168.0.20, define
Service
HeadRequire "Host:.*www.a.com.*"
BackEnd
Address 192.168.0.10
Port 80
End
End
Service
HeadRequire "Host:.*www.b.com.*"
BackEnd
Address 192.168.0.20
Port 80
End
End
in your config file.
3.2 How do I redirect requests to specific back-ends based on the client
address?
You can do it easier via the packet filter you use. If you insist on
having Pound do it use a combination of port redirection and separate
instances of Pound for each port. For example, assume you want intranet
clients (on 192.168.100.0/24) to use the server at 192.168.1.10 and
external clients go to 192.168.1.20. Do the following:
- redirect requests from 192.168.100.0/24 to port 8080
pf: rdr on rl0 from 192.168.100.0/24 to 192.168.100.1 port 80 \
-> localhost port 8080
netfilter: iptables -t nat -A PREROUTING -p tcp \
-s 192.168.100.0/24 --dport 80 -i eth0 -j DNAT \
--to localhost:8080
- redirect requests from anywhere else to port 8081
pf: rdr on rl0 from any to 192.168.100.1 port 80 \
-> localhost port 8081
netfilter: iptables -t nat -A PREROUTING -p tcp \
--dport 80 -i eth0 -j DNAT --to localhost:8081
- have a Pound listener on port 8080 and sending the
requests to 192.168.1.10
- have a Pound listener on port 8081 and sending the
requests to 192.168.1.20
3.3 What happens when my server replies with a redirect?
Depending on configuration, Pound can watch for redirect replies from back-ends
and change them to the correct address. In order for this to happen the
following conditions must be met:
- Pound has "Check30x 1"
- the back-end replies with a redirect. The address of that URL resolves to
the same address as the one Pound is listening on or the address of the
back-end itself.
This feature is commonly used when Pound serves as a HTTPS wrapper,
as the backend redirect to "Location: http://x.y.com" is rewritten as
"Location: https://x.y.com".
4. HTTPS
========
4.1 Can I have Pound force HTTPS connections to certain URLs/back-ends?
Yes - define a Service with a Redirect back-end.
4.2 How can I do virtual hosting with HTTPS?
The simple answer is that neither you, nor anybody else can, due to a
limitation of the HTTPS protocol. In its simplest form an HTTPS (SSL)
connection goes through the following stages:
- negotiation: the client contacts the server, receives a certificate
from it, and negotiates the protocol details (cipher parameters, etc).
- authentication: the client checks that the certificate received matches
the server it wanted and validates that the certificate is correct as
attested by some certificate authority.
- request/response: normal HTTP, encrypted in transit.
As you can see the certificate is sent before any request was received.
Unfortunately, the first request specifies the virtual host that the
client would like to talk to - and it may not match the server name in
the certificate.
4.3 Pound does not start with message "can't read private key"
The file you specify in the ListenHTTPS directive must contain both the
server certificate and the private key to it in PEM format. See the man
page for SSL_CTX_use_PrivateKey_file(3) for details.
4.4 How can a back-end know that the connection is via HTTPS?
Pound can add a header for incoming requests indicating that they were
received via HTTPS. See the details on AddHeader in the man page.
4.5 HTTPS connections fail when Pound runs chrooted
The OpenSSL library requires access to /dev/urandom for its random seed.
The normal device is not accessible in a jail root. You should add a
link to the device to make it accessible. On Linux this would be:
mknod /var/pound/dev/urandom c 1 9
assuming that /var/pound is the root jail.
4.6 How can I force a back-end to generate the correct URL with HTTPS
There is no simple answer to this question - each server and application
have their own way of doing things. If your server does not use absolute
paths then all is well - things will run out of the box. However if some
frames, images, links or a base tag are generated with an absolute path
you must find a way to force the generation with https://.
4.7 How can I find out about the client certificate in my application?
For requests via HTTPS connections Pound can add the details of the
client certificate as headers to each and every request it passes to
the back-end. See the details on HTTPSHeaders in the man page.
4.8 Can Pound use my crypto accelerator hardware?
Pound supports the OpenSSL engine architecture. If your crypto card is
supported by OpenSSL then it is supported by Pound. See the SSLEngine
directive in the man page.
4.9 Can Pound use HTTPS back-end servers?
Yes, but that is not always a very good idea. Such a setup would essentially
make Pound into a "man-in-the-middle" program. Even worse, the certificates
on the back-end would become meaningless - they are seen only by Pound.
5. Session tracking
===================
5.1 Can I have session tracking based on URL and/or Cookie?
Pound can track sessions based on client IP address, a cookie, an URL
parameter or BasicAuthentication. These options are mutually exclusive -
only one of them can be used per UrlGroup.
5.2 When does a session expire?
A session is kept for the specified number of seconds. If during this
time no new request was received the session is discarded.
5.3 Does Pound create/track its own sessions?
No. Pound does not add anything to the requests or the responses - it
uses the tokens generated by the back-end servers exclusively.
6. Logging
==========
6.1 Can I use Webalizer on Pound log files?
Yes. If you use LogLevel 3 or 4 Pound uses one of the standard log
formats that are recognized by applications such as Webalizer. You will
have to remove the time-stamp generated by the syslog - see cut(1) for
details.
6.2 How do I log the original client address in the back-end log?
Pound adds the X-Forwarded-for header with the original client address
to every request. Use it for your logs on the back-end servers.
6.3 How can I separate the Pound log from other syslog messages?
If you use the syslog facility you can configure it to send the pound
messages to a separate file. You may want to separate by severity as
well - normal log messages use LOG_INFO, everything else is not request
information. See syslogd(8) for details on how to configure it.
6.4 How can I separate error messages from normal log messages?
If you use syslog: normal requests are logged at LOG_INFO, everything
else is higher.
If you run without syslog: normal request logging to stdout, everything
else to stderr.
6.5 Why does Pound not log anything when chrooted?
On some systems you need access to /dev/log in order to use the syslog(8)
facility. Create/link the device as needed in the root jail you use.
6.6 Why can't Pound log directly to a file?
This is a security requirement. As things stand, Pound does not write at
all to the disk. The existing tools - such as syslog - allow all the
flexibility one could wish for.
If you absolutely must you can try the patches from Shinji Tanaka (see
http://www.hatena-inc.co.jp/~stanaka/pound/ for details).
7. WebDAV
=========
7.1 I compiled Pound with DAV support but it still rejects the requests
You also need to define "WebDAV 1" in your config file, and (depending on
your server or application) "xHTTP 1" as well.
7.3 Can I use Pound as a front-end for Subversion?
Yes. You may have some problems with using it via HTTPS, but HTTP should
work.
8. Zope
=======
8.1 What configurations is Pound most helpful for?
If you have several servers running on top of a ZEO server, Pound will
allow you to load-balance between them (BTW, this was the original
motivation for developing Pound). Pound also makes for a very good,
light-weight front-end for a single Zope - exposing the Zope Web-server
directly on the big, bad Internet is not a very good idea.
8.2 Can I have virtual hosts in Zope without Apache?
Yes. Despite persistent rumors, the Virtual Host Monster works perfectly
well on its own (dark incantations at midnight under the shade of the
cross-shaped oak branch are NOT required). All you need to do is to
add a VHM in the Zope root, click on the Mappings tab and add whatever
hosts you need.
8.3 Can I have HTTPS for Zope?
Yes. Pound will happily pass SSL requests to Zope. You have three possible
methods to force Zope to generate responses with the https:// prefix:
- if all you need is a specific area to be accessible only through HTTPS
you can add a SiteRoot with the correct name.
- alternately the Pound distribution includes patches for z2.py that
include a new -y flag for a "https://" port.
- finally, for version 2.7 or later you can set it in zope.conf.
8.4 Can I force HTTPS for certain areas in Zope?
Yes. Add a check for the SSL-specific headers in the dtml_header or
whatever equivalent you use. See the details on HTTPSHeaders in the man
page.
9. Miscellaneous/MS
===================
9.1 IE fails to connect to Pound via HTTPS
Define the ciphers to be
"ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
in the config file. We have had reports of IE problems with other
ciphers.
9.2 IE has big delays in getting replies from Pound
Try a shorter Client timeout. IE uses exactly 4 sockets, and as long as
they stay open it won't do anything else. A short Client value will
force the socket(s) to be closed earlier, thus avoiding annoying waits.
9.3 I try to run MS OWA and Pound rejects the requests
Make sure you configured Pound with --enable-msdav. Make sure you
included "WebDAV 1" in the config file. Pray that MS would adhere to
some known standard. Repeat as necessary.
9.4 How can I force OWA to accept HTTPS requests?
Make sure to define
AddHeader "Front-End-Https: on"
in the config file. This will force OWA to generate the responses with
the correct protocol.
Pound-2.8/configure 0000775 0001750 0001750 00000613360 13275266545 013431 0 ustar roseg roseg #! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for pound 2.8.
#
# Report bugs to .
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
#
#
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
&& (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='print -r --'
as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='printf %s\n'
as_echo_n='printf %s'
else
if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
as_echo_n='/usr/ucb/echo -n'
else
as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
as_echo_n_body='eval
arg=$1;
case $arg in #(
*"$as_nl"*)
expr "X$arg" : "X\\(.*\\)$as_nl";
arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
esac;
expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
'
export as_echo_n_body
as_echo_n='sh -c $as_echo_n_body as_echo'
fi
export as_echo_body
as_echo='sh -c $as_echo_body as_echo'
fi
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# IFS
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
$as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there. '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# Use a proper internal environment variable to ensure we don't fall
# into an infinite loop, continuously re-executing ourselves.
if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
_as_can_reexec=no; export _as_can_reexec;
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;;
*x* ) as_opts=-x ;;
* ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
as_fn_exit 255
fi
# We don't want this to propagate to other subprocesses.
{ _as_can_reexec=; unset _as_can_reexec;}
if test "x$CONFIG_SHELL" = x; then
as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
# is contrary to our usage. Disable this feature.
alias -g '\${1+\"\$@\"}'='\"\$@\"'
setopt NO_GLOB_SUBST
else
case \`(set -o) 2>/dev/null\` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
"
as_required="as_fn_return () { (exit \$1); }
as_fn_success () { as_fn_return 0; }
as_fn_failure () { as_fn_return 1; }
as_fn_ret_success () { return 0; }
as_fn_ret_failure () { return 1; }
exitcode=0
as_fn_success || { exitcode=1; echo as_fn_success failed.; }
as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
else
exitcode=1; echo positional parameters were not saved.
fi
test x\$exitcode = x0 || exit 1
test -x / || exit 1"
as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
test \$(( 1 + 1 )) = 2 || exit 1"
if (eval "$as_required") 2>/dev/null; then :
as_have_required=yes
else
as_have_required=no
fi
if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
as_found=false
for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
as_found=:
case $as_dir in #(
/*)
for as_base in sh bash ksh sh5; do
# Try only shells that exist, to save several forks.
as_shell=$as_dir/$as_base
if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
{ $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
CONFIG_SHELL=$as_shell as_have_required=yes
if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
break 2
fi
fi
done;;
esac
as_found=false
done
$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
{ $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
CONFIG_SHELL=$SHELL as_have_required=yes
fi; }
IFS=$as_save_IFS
if test "x$CONFIG_SHELL" != x; then :
export CONFIG_SHELL
# We cannot yet assume a decent shell, so we have to provide a
# neutralization value for shells without unset; and this also
# works around shells that cannot unset nonexistent variables.
# Preserve -v and -x to the replacement shell.
BASH_ENV=/dev/null
ENV=/dev/null
(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
case $- in # ((((
*v*x* | *x*v* ) as_opts=-vx ;;
*v* ) as_opts=-v ;;
*x* ) as_opts=-x ;;
* ) as_opts= ;;
esac
exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
# Admittedly, this is quite paranoid, since all the known shells bail
# out after a failed `exec'.
$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
exit 255
fi
if test x$as_have_required = xno; then :
$as_echo "$0: This script requires a shell more modern than all"
$as_echo "$0: the shells that I found on your system."
if test x${ZSH_VERSION+set} = xset ; then
$as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
$as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
$as_echo "$0: Please tell bug-autoconf@gnu.org and roseg@apsis.ch
$0: about your system, including any error possibly output
$0: before this message. Then install a modern shell, or
$0: manually run the script under such a shell if you do
$0: have one."
fi
exit 1
fi
fi
fi
SHELL=${CONFIG_SHELL-/bin/sh}
export SHELL
# Unset more variables known to interfere with behavior of common tools.
CLICOLOR_FORCE= GREP_OPTIONS=
unset CLICOLOR_FORCE GREP_OPTIONS
## --------------------- ##
## M4sh Shell Functions. ##
## --------------------- ##
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
return $1
} # as_fn_set_status
# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
set +e
as_fn_set_status $1
exit $1
} # as_fn_exit
# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{
case $as_dir in #(
-*) as_dir=./$as_dir;;
esac
test -d "$as_dir" || eval $as_mkdir_p || {
as_dirs=
while :; do
case $as_dir in #(
*\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
} || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
else
as_fn_append ()
{
eval $1=\$$1\$2
}
fi # as_fn_append
# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
}
fi # as_fn_arith
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
$as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
$as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
if expr a : '\(a\)' >/dev/null 2>&1 &&
test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
as_dirname=dirname
else
as_dirname=false
fi
as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
as_lineno_1=$LINENO as_lineno_1a=$LINENO
as_lineno_2=$LINENO as_lineno_2a=$LINENO
eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
# Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
sed -n '
p
/[$]LINENO/=
' <$as_myself |
sed '
s/[$]LINENO.*/&-/
t lineno
b
:lineno
N
:loop
s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
t loop
s/-\n.*//
' >$as_me.lineno &&
chmod +x "$as_me.lineno" ||
{ $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
# If we had to re-execute with $CONFIG_SHELL, we're ensured to have
# already done that, so ensure we don't try to do so again and fall
# in an infinite loop. This has already happened in practice.
_as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
# original and so on. Autoconf is especially sensitive to this).
. "./$as_me.lineno"
# Exit status is that of the last command.
exit
}
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
case `echo 'xy\c'` in
*c*) ECHO_T=' ';; # ECHO_T is single tab character.
xy) ECHO_C='\c';;
*) echo `echo ksh88 bug on AIX 6.1` > /dev/null
ECHO_T=' ';;
esac;;
*)
ECHO_N='-n';;
esac
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
else
rm -f conf$$.dir
mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
if mkdir -p . 2>/dev/null; then
as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
test -n "$DJDIR" || exec 7<&0 &1
# Name of the host.
# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
#
# Initializations.
#
ac_default_prefix=/usr/local
ac_clean_files=
ac_config_libobj_dir=.
LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='pound'
PACKAGE_TARNAME='pound'
PACKAGE_VERSION='2.8'
PACKAGE_STRING='pound 2.8'
PACKAGE_BUGREPORT='roseg@apsis.ch'
PACKAGE_URL=''
ac_unique_file="pound.c"
ac_c_werror_flag=
# Factoring default headers for most tests.
ac_includes_default="\
#include
#ifdef HAVE_SYS_TYPES_H
# include
#endif
#ifdef HAVE_SYS_STAT_H
# include
#endif
#ifdef STDC_HEADERS
# include
# include
#else
# ifdef HAVE_STDLIB_H
# include
# endif
#endif
#ifdef HAVE_STRING_H
# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
# include
# endif
# include
#endif
#ifdef HAVE_STRINGS_H
# include
#endif
#ifdef HAVE_INTTYPES_H
# include
#endif
#ifdef HAVE_STDINT_H
# include
#endif
#ifdef HAVE_UNISTD_H
# include
#endif"
ac_subst_vars='LTLIBOBJS
I_GRP
I_OWNER
LIBOBJS
EGREP
GREP
CPP
C_SUPER
C_GROUP
C_OWNER
C_MAXBUF
C_DH_LEN
C_T_RSA
C_SSL
PTHREAD_CFLAGS
PTHREAD_LIBS
PTHREAD_CC
acx_pthread_config
target_os
target_vendor
target_cpu
target
host_os
host_vendor
host_cpu
host
build_os
build_vendor
build_cpu
build
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
OBJEXT
EXEEXT
ac_ct_CC
CPPFLAGS
LDFLAGS
CFLAGS
CC
target_alias
host_alias
build_alias
LIBS
ECHO_T
ECHO_N
ECHO_C
DEFS
mandir
localedir
libdir
psdir
pdfdir
dvidir
htmldir
infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
datadir
datarootdir
libexecdir
sbindir
bindir
program_transform_name
prefix
exec_prefix
PACKAGE_URL
PACKAGE_BUGREPORT
PACKAGE_STRING
PACKAGE_VERSION
PACKAGE_TARNAME
PACKAGE_NAME
PATH_SEPARATOR
SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
with_ssl
with_t_rsa
with_dh
with_maxbuf
with_owner
with_group
enable_super
enable_pcreposix
enable_tcmalloc
enable_hoard
'
ac_precious_vars='build_alias
host_alias
target_alias
CC
CFLAGS
LDFLAGS
LIBS
CPPFLAGS
CPP'
# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
ac_unrecognized_opts=
ac_unrecognized_sep=
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
exec_prefix=NONE
no_create=
no_recursion=
prefix=NONE
program_prefix=NONE
program_suffix=NONE
program_transform_name=s,x,x,
silent=
site=
srcdir=
verbose=
x_includes=NONE
x_libraries=NONE
# Installation directory options.
# These are left unexpanded so users can "make install exec_prefix=/foo"
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
datarootdir='${prefix}/share'
datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
infodir='${datarootdir}/info'
htmldir='${docdir}'
dvidir='${docdir}'
pdfdir='${docdir}'
psdir='${docdir}'
libdir='${exec_prefix}/lib'
localedir='${datarootdir}/locale'
mandir='${datarootdir}/man'
ac_prev=
ac_dashdash=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
eval $ac_prev=\$ac_option
ac_prev=
continue
fi
case $ac_option in
*=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
*=) ac_optarg= ;;
*) ac_optarg=yes ;;
esac
# Accept the important Cygnus configure options, so we can diagnose typos.
case $ac_dashdash$ac_option in
--)
ac_dashdash=yes ;;
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
-bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
bindir=$ac_optarg ;;
-build | --build | --buil | --bui | --bu)
ac_prev=build_alias ;;
-build=* | --build=* | --buil=* | --bui=* | --bu=*)
build_alias=$ac_optarg ;;
-cache-file | --cache-file | --cache-fil | --cache-fi \
| --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
ac_prev=cache_file ;;
-cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
| --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
cache_file=$ac_optarg ;;
--config-cache | -C)
cache_file=config.cache ;;
-datadir | --datadir | --datadi | --datad)
ac_prev=datadir ;;
-datadir=* | --datadir=* | --datadi=* | --datad=*)
datadir=$ac_optarg ;;
-datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
| --dataroo | --dataro | --datar)
ac_prev=datarootdir ;;
-datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
| --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
datarootdir=$ac_optarg ;;
-disable-* | --disable-*)
ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"enable_$ac_useropt"
"*) ;;
*) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
ac_unrecognized_sep=', ';;
esac
eval enable_$ac_useropt=no ;;
-docdir | --docdir | --docdi | --doc | --do)
ac_prev=docdir ;;
-docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
docdir=$ac_optarg ;;
-dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
ac_prev=dvidir ;;
-dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
dvidir=$ac_optarg ;;
-enable-* | --enable-*)
ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
as_fn_error $? "invalid feature name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"enable_$ac_useropt"
"*) ;;
*) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
ac_unrecognized_sep=', ';;
esac
eval enable_$ac_useropt=\$ac_optarg ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
| --exec | --exe | --ex)
ac_prev=exec_prefix ;;
-exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
| --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
| --exec=* | --exe=* | --ex=*)
exec_prefix=$ac_optarg ;;
-gas | --gas | --ga | --g)
# Obsolete; use --with-gas.
with_gas=yes ;;
-help | --help | --hel | --he | -h)
ac_init_help=long ;;
-help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
ac_init_help=recursive ;;
-help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
ac_init_help=short ;;
-host | --host | --hos | --ho)
ac_prev=host_alias ;;
-host=* | --host=* | --hos=* | --ho=*)
host_alias=$ac_optarg ;;
-htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
ac_prev=htmldir ;;
-htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
| --ht=*)
htmldir=$ac_optarg ;;
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
-includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
| --includ=* | --inclu=* | --incl=* | --inc=*)
includedir=$ac_optarg ;;
-infodir | --infodir | --infodi | --infod | --info | --inf)
ac_prev=infodir ;;
-infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
infodir=$ac_optarg ;;
-libdir | --libdir | --libdi | --libd)
ac_prev=libdir ;;
-libdir=* | --libdir=* | --libdi=* | --libd=*)
libdir=$ac_optarg ;;
-libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
| --libexe | --libex | --libe)
ac_prev=libexecdir ;;
-libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
| --libexe=* | --libex=* | --libe=*)
libexecdir=$ac_optarg ;;
-localedir | --localedir | --localedi | --localed | --locale)
ac_prev=localedir ;;
-localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
localedir=$ac_optarg ;;
-localstatedir | --localstatedir | --localstatedi | --localstated \
| --localstate | --localstat | --localsta | --localst | --locals)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
| --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
ac_prev=mandir ;;
-mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
mandir=$ac_optarg ;;
-nfp | --nfp | --nf)
# Obsolete; use --without-fp.
with_fp=no ;;
-no-create | --no-create | --no-creat | --no-crea | --no-cre \
| --no-cr | --no-c | -n)
no_create=yes ;;
-no-recursion | --no-recursion | --no-recursio | --no-recursi \
| --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
no_recursion=yes ;;
-oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
| --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
| --oldin | --oldi | --old | --ol | --o)
ac_prev=oldincludedir ;;
-oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
| --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
| --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
oldincludedir=$ac_optarg ;;
-prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
ac_prev=prefix ;;
-prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
prefix=$ac_optarg ;;
-program-prefix | --program-prefix | --program-prefi | --program-pref \
| --program-pre | --program-pr | --program-p)
ac_prev=program_prefix ;;
-program-prefix=* | --program-prefix=* | --program-prefi=* \
| --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
program_prefix=$ac_optarg ;;
-program-suffix | --program-suffix | --program-suffi | --program-suff \
| --program-suf | --program-su | --program-s)
ac_prev=program_suffix ;;
-program-suffix=* | --program-suffix=* | --program-suffi=* \
| --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
program_suffix=$ac_optarg ;;
-program-transform-name | --program-transform-name \
| --program-transform-nam | --program-transform-na \
| --program-transform-n | --program-transform- \
| --program-transform | --program-transfor \
| --program-transfo | --program-transf \
| --program-trans | --program-tran \
| --progr-tra | --program-tr | --program-t)
ac_prev=program_transform_name ;;
-program-transform-name=* | --program-transform-name=* \
| --program-transform-nam=* | --program-transform-na=* \
| --program-transform-n=* | --program-transform-=* \
| --program-transform=* | --program-transfor=* \
| --program-transfo=* | --program-transf=* \
| --program-trans=* | --program-tran=* \
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name=$ac_optarg ;;
-pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
ac_prev=pdfdir ;;
-pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
pdfdir=$ac_optarg ;;
-psdir | --psdir | --psdi | --psd | --ps)
ac_prev=psdir ;;
-psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
psdir=$ac_optarg ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
| --sbi=* | --sb=*)
sbindir=$ac_optarg ;;
-sharedstatedir | --sharedstatedir | --sharedstatedi \
| --sharedstated | --sharedstate | --sharedstat | --sharedsta \
| --sharedst | --shareds | --shared | --share | --shar \
| --sha | --sh)
ac_prev=sharedstatedir ;;
-sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
| --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
| --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
| --sha=* | --sh=*)
sharedstatedir=$ac_optarg ;;
-site | --site | --sit)
ac_prev=site ;;
-site=* | --site=* | --sit=*)
site=$ac_optarg ;;
-srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
ac_prev=srcdir ;;
-srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
srcdir=$ac_optarg ;;
-sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
| --syscon | --sysco | --sysc | --sys | --sy)
ac_prev=sysconfdir ;;
-sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
| --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
sysconfdir=$ac_optarg ;;
-target | --target | --targe | --targ | --tar | --ta | --t)
ac_prev=target_alias ;;
-target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
target_alias=$ac_optarg ;;
-v | -verbose | --verbose | --verbos | --verbo | --verb)
verbose=yes ;;
-version | --version | --versio | --versi | --vers | -V)
ac_init_version=: ;;
-with-* | --with-*)
ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"with_$ac_useropt"
"*) ;;
*) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
ac_unrecognized_sep=', ';;
esac
eval with_$ac_useropt=\$ac_optarg ;;
-without-* | --without-*)
ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
as_fn_error $? "invalid package name: $ac_useropt"
ac_useropt_orig=$ac_useropt
ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
case $ac_user_opts in
*"
"with_$ac_useropt"
"*) ;;
*) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
ac_unrecognized_sep=', ';;
esac
eval with_$ac_useropt=no ;;
--x)
# Obsolete; use --with-x.
with_x=yes ;;
-x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
| --x-incl | --x-inc | --x-in | --x-i)
ac_prev=x_includes ;;
-x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
| --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
x_includes=$ac_optarg ;;
-x-libraries | --x-libraries | --x-librarie | --x-librari \
| --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
ac_prev=x_libraries ;;
-x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
-*) as_fn_error $? "unrecognized option: \`$ac_option'
Try \`$0 --help' for more information"
;;
*=*)
ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
# Reject names that are not valid shell variable names.
case $ac_envvar in #(
'' | [0-9]* | *[!_$as_cr_alnum]* )
as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
esac
eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
*)
# FIXME: should be removed in autoconf 3.0.
$as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
$as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
: "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
done
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
as_fn_error $? "missing argument to $ac_option"
fi
if test -n "$ac_unrecognized_opts"; then
case $enable_option_checking in
no) ;;
fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
*) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
fi
# Check all directory arguments for consistency.
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
case $ac_val in
*/ )
ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
eval $ac_var=\$ac_val;;
esac
# Be sure to have absolute directory names.
case $ac_val in
[\\/$]* | ?:[\\/]* ) continue;;
NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
# used to hold the argument of --host etc.
# FIXME: To remove some day.
build=$build_alias
host=$host_alias
target=$target_alias
# FIXME: To remove some day.
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
fi
ac_tool_prefix=
test -n "$host_alias" && ac_tool_prefix=$host_alias-
test "$silent" = yes && exec 6>/dev/null
ac_pwd=`pwd` && test -n "$ac_pwd" &&
ac_ls_di=`ls -di .` &&
ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
as_fn_error $? "working directory cannot be determined"
test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
as_fn_error $? "pwd does not report name of working directory"
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
# Try the directory containing this script, then the parent directory.
ac_confdir=`$as_dirname -- "$as_myself" ||
$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_myself" : 'X\(//\)[^/]' \| \
X"$as_myself" : 'X\(//\)$' \| \
X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_myself" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
srcdir=$ac_confdir
if test ! -r "$srcdir/$ac_unique_file"; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
if test ! -r "$srcdir/$ac_unique_file"; then
test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
fi
ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
ac_abs_confdir=`(
cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
pwd)`
# When building in place, set srcdir=.
if test "$ac_abs_confdir" = "$ac_pwd"; then
srcdir=.
fi
# Remove unnecessary trailing slashes from srcdir.
# Double slashes in file names in object file debugging info
# mess up M-x gdb in Emacs.
case $srcdir in
*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
esac
for ac_var in $ac_precious_vars; do
eval ac_env_${ac_var}_set=\${${ac_var}+set}
eval ac_env_${ac_var}_value=\$${ac_var}
eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
eval ac_cv_env_${ac_var}_value=\$${ac_var}
done
#
# Report the --help message.
#
if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures pound 2.8 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE. See below for descriptions of some of the useful variables.
Defaults for the options are specified in brackets.
Configuration:
-h, --help display this help and exit
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
-q, --quiet, --silent do not print \`checking ...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or \`..']
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
[$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
an installation prefix other than \`$ac_default_prefix' using \`--prefix',
for instance \`--prefix=\$HOME'.
For better control, use the options below.
Fine tuning of the installation directories:
--bindir=DIR user executables [EPREFIX/bin]
--sbindir=DIR system admin executables [EPREFIX/sbin]
--libexecdir=DIR program executables [EPREFIX/libexec]
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
--datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
--datadir=DIR read-only architecture-independent data [DATAROOTDIR]
--infodir=DIR info documentation [DATAROOTDIR/info]
--localedir=DIR locale-dependent data [DATAROOTDIR/locale]
--mandir=DIR man documentation [DATAROOTDIR/man]
--docdir=DIR documentation root [DATAROOTDIR/doc/pound]
--htmldir=DIR html documentation [DOCDIR]
--dvidir=DIR dvi documentation [DOCDIR]
--pdfdir=DIR pdf documentation [DOCDIR]
--psdir=DIR ps documentation [DOCDIR]
_ACEOF
cat <<\_ACEOF
System types:
--build=BUILD configure for building on BUILD [guessed]
--host=HOST cross-compile to build programs to run on HOST [BUILD]
--target=TARGET configure for building compilers for TARGET [HOST]
_ACEOF
fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of pound 2.8:";;
esac
cat <<\_ACEOF
Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-super enable or disable running with supervisor process
(default: enabled)
--enable-pcreposix enable or disable using the pcreposix library
(default: enabled if available)
--enable-tcmalloc enable or disable using the tcmalloc library
(default: enabled if available)
--enable-hoard enable or disable using the hoard library (default:
enabled if available and tcmalloc NOT available)
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-ssl=directory location of OpenSSL package
--with-t_rsa=nnn Time-out for RSA ephemeral keys generation
--with-dh=nnn DH key length parameter (default: 2048, can set to
1024
--with-maxbuf=nnn Value of the MAXBUF parameter (default: 4096)
--with-owner=name The account that will own the files installed by
Pound
--with-group=name The group that will own the files installed by Pound
Some influential environment variables:
CC C compiler command
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L if you have libraries in a
nonstandard directory
LIBS libraries to pass to the linker, e.g. -l
CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if
you have headers in a nonstandard directory
CPP C preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
Report bugs to .
_ACEOF
ac_status=$?
fi
if test "$ac_init_help" = "recursive"; then
# If there are subdirs, report their specific --help.
for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
test -d "$ac_dir" ||
{ cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
continue
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
cd "$ac_dir" || { ac_status=$?; continue; }
# Check for guested configure.
if test -f "$ac_srcdir/configure.gnu"; then
echo &&
$SHELL "$ac_srcdir/configure.gnu" --help=recursive
elif test -f "$ac_srcdir/configure"; then
echo &&
$SHELL "$ac_srcdir/configure" --help=recursive
else
$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
fi || ac_status=$?
cd "$ac_pwd" || { ac_status=$?; break; }
done
fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
pound configure 2.8
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
exit
fi
## ------------------------ ##
## Autoconf initialization. ##
## ------------------------ ##
# ac_fn_c_try_compile LINENO
# --------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_compile
# ac_fn_c_try_link LINENO
# -----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_link ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
rm -f conftest.$ac_objext conftest$ac_exeext
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest$ac_exeext && {
test "$cross_compiling" = yes ||
test -x conftest$ac_exeext
}; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
# Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
# created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
# interfere with the next link command; also delete a directory that is
# left behind by Apple's compiler. We do this before executing the actions.
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_link
# ac_fn_c_try_cpp LINENO
# ----------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
ac_fn_c_try_cpp ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if { { ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
grep -v '^ *+' conftest.err >conftest.er1
cat conftest.er1 >&5
mv -f conftest.er1 conftest.err
fi
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } > conftest.i && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then :
ac_retval=0
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=1
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_cpp
# ac_fn_c_try_run LINENO
# ----------------------
# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
# that executables *can* be run.
ac_fn_c_try_run ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
{ { case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_try") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then :
ac_retval=0
else
$as_echo "$as_me: program exited with status $ac_status" >&5
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_retval=$ac_status
fi
rm -rf conftest.dSYM conftest_ipa8_conftest.oo
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
as_fn_set_status $ac_retval
} # ac_fn_c_try_run
# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists, giving a warning if it cannot be compiled using
# the include files in INCLUDES and setting the cache variable VAR
# accordingly.
ac_fn_c_check_header_mongrel ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
if eval \${$3+:} false; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
else
# Is the header compilable?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
$as_echo_n "checking $2 usability... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_header_compiler=yes
else
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
$as_echo "$ac_header_compiler" >&6; }
# Is the header present?
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
$as_echo_n "checking $2 presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <$2>
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
ac_header_preproc=yes
else
ac_header_preproc=no
fi
rm -f conftest.err conftest.i conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
$as_echo "$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
yes:no: )
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
;;
no:yes:* )
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
( $as_echo "## ----------------------------- ##
## Report this to roseg@apsis.ch ##
## ----------------------------- ##"
) | sed "s/^/$as_me: WARNING: /" >&2
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=\$ac_header_compiler"
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
fi
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_mongrel
# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
# -------------------------------------------------------
# Tests whether HEADER exists and can be compiled using the include files in
# INCLUDES, setting the cache variable VAR accordingly.
ac_fn_c_check_header_compile ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
#include <$2>
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
eval "$3=yes"
else
eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_header_compile
# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
# -------------------------------------------
# Tests whether TYPE exists after having included INCLUDES, setting cache
# variable VAR accordingly.
ac_fn_c_check_type ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
eval "$3=no"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof ($2))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$4
int
main ()
{
if (sizeof (($2)))
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
eval "$3=yes"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_type
# ac_fn_c_check_func LINENO FUNC VAR
# ----------------------------------
# Tests whether FUNC exists, setting the cache variable VAR accordingly
ac_fn_c_check_func ()
{
as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
$as_echo_n "checking for $2... " >&6; }
if eval \${$3+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Define $2 to an innocuous variant, in case declares $2.
For example, HP-UX 11i declares gettimeofday. */
#define $2 innocuous_$2
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $2 (); below.
Prefer to if __STDC__ is defined, since
exists even on freestanding compilers. */
#ifdef __STDC__
# include
#else
# include
#endif
#undef $2
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $2 ();
/* 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_$2 || defined __stub___$2
choke me
#endif
int
main ()
{
return $2 ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
eval "$3=yes"
else
eval "$3=no"
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
eval ac_res=\$$3
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
$as_echo "$ac_res" >&6; }
eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
} # ac_fn_c_check_func
cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by pound $as_me 2.8, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
_ACEOF
exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
## Platform. ##
## --------- ##
hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
uname -m = `(uname -m) 2>/dev/null || echo unknown`
uname -r = `(uname -r) 2>/dev/null || echo unknown`
uname -s = `(uname -s) 2>/dev/null || echo unknown`
uname -v = `(uname -v) 2>/dev/null || echo unknown`
/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
_ASUNAME
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
$as_echo "PATH: $as_dir"
done
IFS=$as_save_IFS
} >&5
cat >&5 <<_ACEOF
## ----------- ##
## Core tests. ##
## ----------- ##
_ACEOF
# Keep a trace of the command line.
# Strip out --no-create and --no-recursion so they do not pile up.
# Strip out --silent because we don't want to record it for future runs.
# Also quote any args containing shell meta-characters.
# Make two passes to allow for proper duplicate-argument suppression.
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
ac_must_keep_next=false
for ac_pass in 1 2
do
for ac_arg
do
case $ac_arg in
-no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
continue ;;
*\'*)
ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
case $ac_pass in
1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
2)
as_fn_append ac_configure_args1 " '$ac_arg'"
if test $ac_must_keep_next = true; then
ac_must_keep_next=false # Got value, back to normal.
else
case $ac_arg in
*=* | --config-cache | -C | -disable-* | --disable-* \
| -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
| -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
| -with-* | --with-* | -without-* | --without-* | --x)
case "$ac_configure_args0 " in
"$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
esac
;;
-* ) ac_must_keep_next=true ;;
esac
fi
as_fn_append ac_configure_args " '$ac_arg'"
;;
esac
done
done
{ ac_configure_args0=; unset ac_configure_args0;}
{ ac_configure_args1=; unset ac_configure_args1;}
# When interrupted or exit'd, cleanup temporary files, and complete
# config.log. We remove comments because anyway the quotes in there
# would cause problems or look ugly.
# WARNING: Use '\'' to represent an apostrophe within the trap.
# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
# Save into config.log some information that might help in debugging.
{
echo
$as_echo "## ---------------- ##
## Cache variables. ##
## ---------------- ##"
echo
# The following way of writing the cache mishandles newlines in values,
(
for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
eval ac_val=\$$ac_var
case $ac_val in #(
*${as_nl}*)
case $ac_var in #(
*_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
esac
case $ac_var in #(
_ | IFS | as_nl) ;; #(
BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
*) { eval $ac_var=; unset $ac_var;} ;;
esac ;;
esac
done
(set) 2>&1 |
case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
*${as_nl}ac_space=\ *)
sed -n \
"s/'\''/'\''\\\\'\'''\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
;; #(
*)
sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
esac |
sort
)
echo
$as_echo "## ----------------- ##
## Output variables. ##
## ----------------- ##"
echo
for ac_var in $ac_subst_vars
do
eval ac_val=\$$ac_var
case $ac_val in
*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
esac
$as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
if test -n "$ac_subst_files"; then
$as_echo "## ------------------- ##
## File substitutions. ##
## ------------------- ##"
echo
for ac_var in $ac_subst_files
do
eval ac_val=\$$ac_var
case $ac_val in
*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
esac
$as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
fi
if test -s confdefs.h; then
$as_echo "## ----------- ##
## confdefs.h. ##
## ----------- ##"
echo
cat confdefs.h
echo
fi
test "$ac_signal" != 0 &&
$as_echo "$as_me: caught signal $ac_signal"
$as_echo "$as_me: exit $exit_status"
} >&5
rm -f core *.core core.conftest.* &&
rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
' 0
for ac_signal in 1 2 13 15; do
trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0
# confdefs.h avoids OS command line length limits that DEFS can exceed.
rm -f -r conftest* confdefs.h
$as_echo "/* confdefs.h */" > confdefs.h
# Predefined preprocessor variables.
cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF
cat >>confdefs.h <<_ACEOF
#define PACKAGE_URL "$PACKAGE_URL"
_ACEOF
# Let the site file select an alternate cache file if it wants to.
# Prefer an explicitly selected file to automatically selected ones.
ac_site_file1=NONE
ac_site_file2=NONE
if test -n "$CONFIG_SITE"; then
# We do not want a PATH search for config.site.
case $CONFIG_SITE in #((
-*) ac_site_file1=./$CONFIG_SITE;;
*/*) ac_site_file1=$CONFIG_SITE;;
*) ac_site_file1=./$CONFIG_SITE;;
esac
elif test "x$prefix" != xNONE; then
ac_site_file1=$prefix/share/config.site
ac_site_file2=$prefix/etc/config.site
else
ac_site_file1=$ac_default_prefix/share/config.site
ac_site_file2=$ac_default_prefix/etc/config.site
fi
for ac_site_file in "$ac_site_file1" "$ac_site_file2"
do
test "x$ac_site_file" = xNONE && continue
if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
. "$ac_site_file" \
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
See \`config.log' for more details" "$LINENO" 5; }
fi
done
if test -r "$cache_file"; then
# Some versions of bash will fail to source /dev/null (special files
# actually), so we avoid doing that. DJGPP emulates it as a regular file.
if test /dev/null != "$cache_file" && test -f "$cache_file"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
$as_echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
[\\/]* | ?:[\\/]* ) . "$cache_file";;
*) . "./$cache_file";;
esac
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
$as_echo "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
for ac_var in $ac_precious_vars; do
eval ac_old_set=\$ac_cv_env_${ac_var}_set
eval ac_new_set=\$ac_env_${ac_var}_set
eval ac_old_val=\$ac_cv_env_${ac_var}_value
eval ac_new_val=\$ac_env_${ac_var}_value
case $ac_old_set,$ac_new_set in
set,)
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
ac_cache_corrupted=: ;;
,set)
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
ac_cache_corrupted=: ;;
,);;
*)
if test "x$ac_old_val" != "x$ac_new_val"; then
# differences in whitespace do not lead to failure.
ac_old_val_w=`echo x $ac_old_val`
ac_new_val_w=`echo x $ac_new_val`
if test "$ac_old_val_w" != "$ac_new_val_w"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
ac_cache_corrupted=:
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
eval $ac_var=\$ac_old_val
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
fi;;
esac
# Pass precious variables to config.status.
if test "$ac_new_set" = set; then
case $ac_new_val in
*\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
*) ac_arg=$ac_var=$ac_new_val ;;
esac
case " $ac_configure_args " in
*" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
*) as_fn_append ac_configure_args " '$ac_arg'" ;;
esac
fi
done
if $ac_cache_corrupted; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
{ $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
## -------------------- ##
## Main body of script. ##
## -------------------- ##
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers config.h"
# Checks for programs.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test "x$ac_ct_CC" = x; then
CC=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
CC=$ac_ct_CC
fi
else
CC="$ac_cv_prog_CC"
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
ac_prog_rejected=no
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
set dummy $ac_cv_prog_CC
shift
if test $# != 0; then
# We chose a different compiler from the bogus one.
# However, it has the same basename, so the bogon will be chosen
# first if we set CC to just the basename; use the full file name.
shift
ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
fi
fi
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
for ac_prog in cl.exe
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
$as_echo "$CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$CC" && break
done
fi
if test -z "$CC"; then
ac_ct_CC=$CC
for ac_prog in cl.exe
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_ac_ct_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
$as_echo "$ac_ct_CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
test -n "$ac_ct_CC" && break
done
if test "x$ac_ct_CC" = x; then
CC=""
else
case $cross_compiling:$ac_tool_warned in
yes:)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
ac_tool_warned=yes ;;
esac
CC=$ac_ct_CC
fi
fi
fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
set X $ac_compile
ac_compiler=$2
for ac_option in --version -v -V -qversion; do
{ { ac_try="$ac_compiler $ac_option >&5"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
if test -s conftest.err; then
sed '10a\
... rest of stderr output deleted ...
10q' conftest.err >conftest.er1
cat conftest.er1 >&5
fi
rm -f conftest.er1 conftest.err
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
done
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
$as_echo_n "checking whether the C compiler works... " >&6; }
ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
# The possible output files:
ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
ac_rmfiles=
for ac_file in $ac_files
do
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
* ) ac_rmfiles="$ac_rmfiles $ac_file";;
esac
done
rm -f $ac_rmfiles
if { { ac_try="$ac_link_default"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link_default") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then :
# Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
# in a Makefile. We should not override ac_cv_exeext if it was cached,
# so that the user can short-circuit this test for compilers unknown to
# Autoconf.
for ac_file in $ac_files ''
do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
;;
[ab].out )
# We found the default executable, but exeext='' is most
# certainly right.
break;;
*.* )
if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
then :; else
ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
fi
# We set ac_cv_exeext here because the later test for it is not
# safe: cross compilers may not add the suffix if given an `-o'
# argument, so we may need to know it at that point already.
# Even if this section looks crufty: it has the advantage of
# actually working.
break;;
* )
break;;
esac
done
test "$ac_cv_exeext" = no && ac_cv_exeext=
else
ac_file=''
fi
if test -z "$ac_file"; then :
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
See \`config.log' for more details" "$LINENO" 5; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
$as_echo_n "checking for C compiler default output file name... " >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext
rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
$as_echo_n "checking for suffix of executables... " >&6; }
if { { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then :
# If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
# `rm'.
for ac_file in conftest.exe conftest conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
break;;
* ) break;;
esac
done
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
$as_echo "$ac_cv_exeext" >&6; }
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
int
main ()
{
FILE *f = fopen ("conftest.out", "w");
return ferror (f) || fclose (f) != 0;
;
return 0;
}
_ACEOF
ac_clean_files="$ac_clean_files conftest.out"
# Check that the compiler produces executables we can run. If not, either
# the compiler is broken, or we cross compile.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
$as_echo_n "checking whether we are cross compiling... " >&6; }
if test "$cross_compiling" != yes; then
{ { ac_try="$ac_link"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_link") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }
if { ac_try='./conftest$ac_cv_exeext'
{ { case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_try") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; }; then
cross_compiling=no
else
if test "$cross_compiling" = maybe; then
cross_compiling=yes
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
$as_echo "$cross_compiling" >&6; }
rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
ac_clean_files=$ac_clean_files_save
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
$as_echo_n "checking for suffix of object files... " >&6; }
if ${ac_cv_objext+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
rm -f conftest.o conftest.obj
if { { ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
$as_echo "$ac_try_echo"; } >&5
(eval "$ac_compile") 2>&5
ac_status=$?
$as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
test $ac_status = 0; }; then :
for ac_file in conftest.o conftest.obj conftest.*; do
test -f "$ac_file" || continue;
case $ac_file in
*.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
if ${ac_cv_c_compiler_gnu+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
#ifndef __GNUC__
choke me
#endif
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_compiler_gnu=yes
else
ac_compiler_gnu=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
$as_echo "$ac_cv_c_compiler_gnu" >&6; }
if test $ac_compiler_gnu = yes; then
GCC=yes
else
GCC=
fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
$as_echo_n "checking whether $CC accepts -g... " >&6; }
if ${ac_cv_prog_cc_g+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_save_c_werror_flag=$ac_c_werror_flag
ac_c_werror_flag=yes
ac_cv_prog_cc_g=no
CFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_g=yes
else
CFLAGS=""
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
ac_c_werror_flag=$ac_save_c_werror_flag
CFLAGS="-g"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_g=yes
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_c_werror_flag=$ac_save_c_werror_flag
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
if test "$GCC" = yes; then
CFLAGS="-g -O2"
else
CFLAGS="-g"
fi
else
if test "$GCC" = yes; then
CFLAGS="-O2"
else
CFLAGS=
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
if ${ac_cv_prog_cc_c89+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_prog_cc_c89=no
ac_save_CC=$CC
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
static char *e (p, i)
char **p;
int i;
{
return p[i];
}
static char *f (char * (*g) (char **, int), char **p, ...)
{
char *s;
va_list v;
va_start (v,p);
s = g (p, va_arg (v,int));
va_end (v);
return s;
}
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
function prototypes and stuff, but not '\xHH' hex character constants.
These don't provoke an error unfortunately, instead are silently treated
as 'x'. The following induces an error, until -std is added to get
proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
array size at least. It's necessary to write '\x00'==0 to get something
that's true only with -std. */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];
/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
inside strings and character constants. */
#define FOO(x) 'x'
int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
int argc;
char **argv;
int
main ()
{
return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
;
return 0;
}
_ACEOF
for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
CC="$ac_save_CC $ac_arg"
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_c89=$ac_arg
fi
rm -f core conftest.err conftest.$ac_objext
test "x$ac_cv_prog_cc_c89" != "xno" && break
done
rm -f conftest.$ac_ext
CC=$ac_save_CC
fi
# AC_CACHE_VAL
case "x$ac_cv_prog_cc_c89" in
x)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
$as_echo "none needed" >&6; } ;;
xno)
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
$as_echo "unsupported" >&6; } ;;
*)
CC="$CC $ac_cv_prog_cc_c89"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
esac
if test "x$ac_cv_prog_cc_c89" != xno; then :
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
if ${am_cv_prog_cc_c_o+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
;
return 0;
}
_ACEOF
# Make sure it works both with $CC and with simple cc.
# Following AC_PROG_CC_C_O, we do the test twice because some
# compilers refuse to overwrite an existing .o file with -o,
# though they will create one.
am_cv_prog_cc_c_o=yes
for am_i in 1 2; do
if { echo "$as_me:$LINENO: $CC -c conftest.$ac_ext -o conftest2.$ac_objext" >&5
($CC -c conftest.$ac_ext -o conftest2.$ac_objext) >&5 2>&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } \
&& test -f conftest2.$ac_objext; then
: OK
else
am_cv_prog_cc_c_o=no
break
fi
done
rm -f core conftest*
unset am_i
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
$as_echo "$am_cv_prog_cc_c_o" >&6; }
if test "$am_cv_prog_cc_c_o" != yes; then
# Losing compiler, so override with the script.
# FIXME: It is wrong to rewrite CC.
# But if we don't then we get into trouble of one sort or another.
# A longer-term fix would be to have automake use am__CC in this case,
# and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
CC="$am_aux_dir/compile $CC"
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_aux_dir=
for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
if test -f "$ac_dir/install-sh"; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install-sh -c"
break
elif test -f "$ac_dir/install.sh"; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/install.sh -c"
break
elif test -f "$ac_dir/shtool"; then
ac_aux_dir=$ac_dir
ac_install_sh="$ac_aux_dir/shtool install -c"
break
fi
done
if test -z "$ac_aux_dir"; then
as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
fi
# These three variables are undocumented and unsupported,
# and are intended to be withdrawn in a future Autoconf release.
# They can cause serious problems if a builder's source tree is in a directory
# whose full name contains unusual characters.
ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
# Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or
# incompatible versions:
# SysV /etc/install, /usr/sbin/install
# SunOS /usr/etc/install
# IRIX /sbin/install
# AIX /bin/install
# AmigaOS /C/install, which installs bootblocks on floppy discs
# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
# AFS /usr/afsws/bin/install, which mishandles nonexistent args
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# OS/2's system install, which has a completely different semantic
# ./install, which can be erroneously created by make from ./install.sh.
# Reject install programs that cannot install multiple files.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
$as_echo_n "checking for a BSD-compatible install... " >&6; }
if test -z "$INSTALL"; then
if ${ac_cv_path_install+:} false; then :
$as_echo_n "(cached) " >&6
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
# Account for people who put trailing slashes in PATH elements.
case $as_dir/ in #((
./ | .// | /[cC]/* | \
/etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
/usr/ucb/* ) ;;
*)
# OSF1 and SCO ODT 3.0 have their own names for install.
# Don't use installbsd from OSF since it installs stuff as root
# by default.
for ac_prog in ginstall scoinst install; do
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
if test $ac_prog = install &&
grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# AIX install. It has an incompatible calling convention.
:
elif test $ac_prog = install &&
grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
# program-specific install script used by HP pwplus--don't use.
:
else
rm -rf conftest.one conftest.two conftest.dir
echo one > conftest.one
echo two > conftest.two
mkdir conftest.dir
if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
test -s conftest.one && test -s conftest.two &&
test -s conftest.dir/conftest.one &&
test -s conftest.dir/conftest.two
then
ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
break 3
fi
fi
fi
done
done
;;
esac
done
IFS=$as_save_IFS
rm -rf conftest.one conftest.two conftest.dir
fi
if test "${ac_cv_path_install+set}" = set; then
INSTALL=$ac_cv_path_install
else
# As a last resort, use the slow shell script. Don't cache a
# value for INSTALL within a source directory, because that will
# break other packages using the cache if that directory is
# removed, or if the value is a relative name.
INSTALL=$ac_install_sh
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
$as_echo "$INSTALL" >&6; }
# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
# It thinks the first close brace ends the variable substitution.
test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
$as_echo_n "checking build system type... " >&6; }
if ${ac_cv_build+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_build_alias=$build_alias
test "x$ac_build_alias" = x &&
ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
test "x$ac_build_alias" = x &&
as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
set x $ac_cv_build
shift
build_cpu=$1
build_vendor=$2
shift; shift
# Remember, the first character of IFS is used to create $*,
# except with old shells:
build_os=$*
IFS=$ac_save_IFS
case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
$as_echo_n "checking host system type... " >&6; }
if ${ac_cv_host+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$host_alias" = x; then
ac_cv_host=$ac_cv_build
else
ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
set x $ac_cv_host
shift
host_cpu=$1
host_vendor=$2
shift; shift
# Remember, the first character of IFS is used to create $*,
# except with old shells:
host_os=$*
IFS=$ac_save_IFS
case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
$as_echo_n "checking target system type... " >&6; }
if ${ac_cv_target+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "x$target_alias" = x; then
ac_cv_target=$ac_cv_host
else
ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
as_fn_error $? "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
$as_echo "$ac_cv_target" >&6; }
case $ac_cv_target in
*-*-*) ;;
*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
esac
target=$ac_cv_target
ac_save_IFS=$IFS; IFS='-'
set x $ac_cv_target
shift
target_cpu=$1
target_vendor=$2
shift; shift
# Remember, the first character of IFS is used to create $*,
# except with old shells:
target_os=$*
IFS=$ac_save_IFS
case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
# The aliases save the names the user supplied, while $host etc.
# will get canonicalized.
test -n "$target_alias" &&
test "$program_prefix$program_suffix$program_transform_name" = \
NONENONEs,x,x, &&
program_prefix=${target_alias}-
# Pound - the reverse-proxy load-balancer
# Copyright (C) 2002-2007 Apsis GmbH
#
# This file is part of Pound.
#
# Pound is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Pound is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Contact information:
# Apsis GmbH
# P.O.Box
# 8707 Uetikon am See
# Switzerland
# Tel: +41-44-920 4904
# EMail: roseg@apsis.ch
CPPFLAGS="${CPPFLAGS} -D_REENTRANT -D_THREAD_SAFE"
# if the compiler is gcc, test which flags are supported
if test "${CC}" = "gcc"
then
ac_c_werror_flag=yes
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking gcc arguments" >&5
$as_echo_n "checking gcc arguments... " >&6; }
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wstrict-prototypes"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int x;
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
CFLAGS="$save_CFLAGS"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -Wno-unused-result"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int x;
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
CFLAGS="$save_CFLAGS"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -pipe"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int x;
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
else
CFLAGS="$save_CFLAGS"
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CFLAGS" >&5
$as_echo "$CFLAGS" >&6; }
ac_c_werror_flag=""
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking for threads library and/or flags ***" >&5
$as_echo "$as_me: *** Checking for threads library and/or flags ***" >&6;}
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
$as_echo_n "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pthread_join ();
int
main ()
{
return pthread_join ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
acx_pthread_ok=yes
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
$as_echo "$acx_pthread_ok" >&6; }
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work without any flags" >&5
$as_echo_n "checking whether pthreads work without any flags... " >&6; }
;;
-*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether pthreads work with $flag" >&5
$as_echo_n "checking whether pthreads work with $flag... " >&6; }
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
# Extract the first word of "pthread-config", so it can be a program name with args.
set dummy pthread-config; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_acx_pthread_config+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$acx_pthread_config"; then
ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_acx_pthread_config="yes"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
fi
fi
acx_pthread_config=$ac_cv_prog_acx_pthread_config
if test -n "$acx_pthread_config"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_config" >&5
$as_echo "$acx_pthread_config" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for the pthreads library -l$flag" >&5
$as_echo_n "checking for the pthreads library -l$flag... " >&6; }
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
int
main ()
{
pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0);
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
acx_pthread_ok=yes
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $acx_pthread_ok" >&5
$as_echo "$acx_pthread_ok" >&6; }
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for joinable pthread attribute" >&5
$as_echo_n "checking for joinable pthread attribute... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
int
main ()
{
int attr=PTHREAD_CREATE_JOINABLE;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ok=PTHREAD_CREATE_JOINABLE
else
ok=unknown
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test x"$ok" = xunknown; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
int
main ()
{
int attr=PTHREAD_CREATE_UNDETACHED;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ok=PTHREAD_CREATE_UNDETACHED
else
ok=unknown
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
$as_echo "#define PTHREAD_CREATE_JOINABLE \$ok" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${ok}" >&5
$as_echo "${ok}" >&6; }
if test x"$ok" = xunknown; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: we do not know how to create joinable pthreads" >&5
$as_echo "$as_me: WARNING: we do not know how to create joinable pthreads" >&2;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if more special flags are required for pthreads" >&5
$as_echo_n "checking if more special flags are required for pthreads... " >&6; }
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${flag}" >&5
$as_echo "${flag}" >&6; }
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
# Extract the first word of "cc_r", so it can be a program name with args.
set dummy cc_r; ac_word=$2
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
$as_echo_n "checking for $ac_word... " >&6; }
if ${ac_cv_prog_PTHREAD_CC+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -n "$PTHREAD_CC"; then
ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
else
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_exec_ext in '' $ac_executable_extensions; do
if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_PTHREAD_CC="cc_r"
$as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
done
IFS=$as_save_IFS
test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
fi
fi
PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
if test -n "$PTHREAD_CC"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PTHREAD_CC" >&5
$as_echo "$PTHREAD_CC" >&6; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
$as_echo "no" >&6; }
fi
else
PTHREAD_CC="$CC"
fi
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
LIBS="$PTHREAD_LIBS $LIBS"; CFLAGS="$CFLAGS $PTHREAD_CFLAGS"; CC="$PTHREAD_CC"; LDFLAGS="${LDFLAGS} ${PTHREAD_CFLAGS}"
:
else
acx_pthread_ok=no
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Parsing options ***" >&5
$as_echo "$as_me: *** Parsing options ***" >&6;}
# Check whether --with-ssl was given.
if test "${with_ssl+set}" = set; then :
withval=$with_ssl; CPPFLAGS="-I${with_ssl}/include ${CPPFLAGS}"; LDFLAGS="-L${with_ssl}/lib ${LDFLAGS}"; C_SSL="${with_ssl}"
else
C_SSL=""
fi
# Check whether --with-t_rsa was given.
if test "${with_t_rsa+set}" = set; then :
withval=$with_t_rsa; CPPFLAGS="-DT_RSA_KEYS=${with_t_rsa} ${CPPFLAGS}"; C_T_RSA="${with_t_rsa}"
else
C_T_RSA="0"
fi
# Check whether --with-dh was given.
if test "${with_dh+set}" = set; then :
withval=$with_dh; CPPFLAGS="-DDH_LEN=${with_dh} ${CPPFLAGS}"; C_DH_LEN="${with_dh}"
else
CPPFLAGS="-DDH_LEN=2048 ${CPPFLAGS}"; C_DH_LEN="2048"
fi
# Check whether --with-maxbuf was given.
if test "${with_maxbuf+set}" = set; then :
withval=$with_maxbuf; CPPFLAGS="-DMAXBUF=${with_maxbuf} ${CPPFLAGS}"; C_MAXBUF="${with_maxbuf}"
else
C_MAXBUF="0"
fi
I_OWNER=""
# Check whether --with-owner was given.
if test "${with_owner+set}" = set; then :
withval=$with_owner; I_OWNER="${with_owner}"; C_OWNER="${with_owner}"
else
C_OWNER=""
fi
I_GRP=""
# Check whether --with-group was given.
if test "${with_group+set}" = set; then :
withval=$with_group; I_GRP="${with_group}"; C_GROUP="${with_group}"
else
C_GROUP=""
fi
# Check whether --enable-super was given.
if test "${enable_super+set}" = set; then :
enableval=$enable_super; test ${enableval} = "yes" && CFLAGS="${CFLAGS} -DUPER"; C_SUPER="1"
else
CFLAGS="${CFLAGS} -DUPER"; C_SUPER="0"
fi
# Check whether --enable-pcreposix was given.
if test "${enable_pcreposix+set}" = set; then :
enableval=$enable_pcreposix; C_PCREPOSIX=${enableval}
else
C_PCREPOSIX=yes
fi
# Check whether --enable-tcmalloc was given.
if test "${enable_tcmalloc+set}" = set; then :
enableval=$enable_tcmalloc; C_TCMALLOC=${enableval}
else
C_TCMALLOC=yes
fi
# Check whether --enable-hoard was given.
if test "${enable_hoard+set}" = set; then :
enableval=$enable_hoard; C_HOARD=${enableval}
else
C_HOARD=yes
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking for libraries ***" >&5
$as_echo "$as_me: *** Checking for libraries ***" >&6;}
LIBS="${LIBS} -lm"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
$as_echo_n "checking for dlopen in -ldl... " >&6; }
if ${ac_cv_lib_dl_dlopen+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char dlopen ();
int
main ()
{
return dlopen ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_dl_dlopen=yes
else
ac_cv_lib_dl_dlopen=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_LIBDL 1
_ACEOF
LIBS="-ldl $LIBS"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socket in -lsocket" >&5
$as_echo_n "checking for socket in -lsocket... " >&6; }
if ${ac_cv_lib_socket_socket+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lsocket $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char socket ();
int
main ()
{
return socket ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_socket_socket=yes
else
ac_cv_lib_socket_socket=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_socket" >&5
$as_echo "$ac_cv_lib_socket_socket" >&6; }
if test "x$ac_cv_lib_socket_socket" = xyes; then :
LIBS="-lsocket -lnsl ${LIBS}"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for hstrerror in -lresolv" >&5
$as_echo_n "checking for hstrerror in -lresolv... " >&6; }
if ${ac_cv_lib_resolv_hstrerror+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lresolv $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char hstrerror ();
int
main ()
{
return hstrerror ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_resolv_hstrerror=yes
else
ac_cv_lib_resolv_hstrerror=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_resolv_hstrerror" >&5
$as_echo "$ac_cv_lib_resolv_hstrerror" >&6; }
if test "x$ac_cv_lib_resolv_hstrerror" = xyes; then :
LIBS="-lresolv ${LIBS}"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BIO_new in -lcrypto" >&5
$as_echo_n "checking for BIO_new in -lcrypto... " >&6; }
if ${ac_cv_lib_crypto_BIO_new+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lcrypto $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char BIO_new ();
int
main ()
{
return BIO_new ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_crypto_BIO_new=yes
else
ac_cv_lib_crypto_BIO_new=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_BIO_new" >&5
$as_echo "$ac_cv_lib_crypto_BIO_new" >&6; }
if test "x$ac_cv_lib_crypto_BIO_new" = xyes; then :
LIBS="-lcrypto ${LIBS}"
else
echo 'Missing OpenSSL (-lcrypto) - aborted'; exit 1
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_CTX_new in -lssl" >&5
$as_echo_n "checking for SSL_CTX_new in -lssl... " >&6; }
if ${ac_cv_lib_ssl_SSL_CTX_new+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lssl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char SSL_CTX_new ();
int
main ()
{
return SSL_CTX_new ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_ssl_SSL_CTX_new=yes
else
ac_cv_lib_ssl_SSL_CTX_new=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_CTX_new" >&5
$as_echo "$ac_cv_lib_ssl_SSL_CTX_new" >&6; }
if test "x$ac_cv_lib_ssl_SSL_CTX_new" = xyes; then :
LIBS="-lssl ${LIBS}"
else
echo 'Missing OpenSSL (-lssl) - aborted'; exit 1
fi
if test x"$C_PCREPOSIX" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for regcomp in -lpcreposix" >&5
$as_echo_n "checking for regcomp in -lpcreposix... " >&6; }
if ${ac_cv_lib_pcreposix_regcomp+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpcreposix $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char regcomp ();
int
main ()
{
return regcomp ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_pcreposix_regcomp=yes
else
ac_cv_lib_pcreposix_regcomp=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regcomp" >&5
$as_echo "$ac_cv_lib_pcreposix_regcomp" >&6; }
if test "x$ac_cv_lib_pcreposix_regcomp" = xyes; then :
LIBS="-lpcreposix ${LIBS}";
$as_echo "#define HAVE_LIBPCREPOSIX 1" >>confdefs.h
else
save_LIBS="$LIBS"
LIBS="-lpcre $LIBS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for regexec in -lpcreposix" >&5
$as_echo_n "checking for regexec in -lpcreposix... " >&6; }
if ${ac_cv_lib_pcreposix_regexec+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpcreposix $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char regexec ();
int
main ()
{
return regexec ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_pcreposix_regexec=yes
else
ac_cv_lib_pcreposix_regexec=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pcreposix_regexec" >&5
$as_echo "$ac_cv_lib_pcreposix_regexec" >&6; }
if test "x$ac_cv_lib_pcreposix_regexec" = xyes; then :
LIBS="-lpcreposix -lpcre $save_LIBS";
$as_echo "#define HAVE_LIBPCREPOSIX 1" >>confdefs.h
else
LIBS="$save_LIBS"
fi
fi
fi
if test x"$C_TCMALLOC" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -ltcmalloc" >&5
$as_echo_n "checking for malloc in -ltcmalloc... " >&6; }
if ${ac_cv_lib_tcmalloc_malloc+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ltcmalloc $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char malloc ();
int
main ()
{
return malloc ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_tcmalloc_malloc=yes
else
ac_cv_lib_tcmalloc_malloc=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_tcmalloc_malloc" >&5
$as_echo "$ac_cv_lib_tcmalloc_malloc" >&6; }
if test "x$ac_cv_lib_tcmalloc_malloc" = xyes; then :
LIBS="${LIBS} -ltcmalloc"
fi
else
if test x"$C_HOARD" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for malloc in -lhoard" >&5
$as_echo_n "checking for malloc in -lhoard... " >&6; }
if ${ac_cv_lib_hoard_malloc+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lhoard $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char malloc ();
int
main ()
{
return malloc ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_hoard_malloc=yes
else
ac_cv_lib_hoard_malloc=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_hoard_malloc" >&5
$as_echo "$ac_cv_lib_hoard_malloc" >&6; }
if test "x$ac_cv_lib_hoard_malloc" = xyes; then :
LIBS="${LIBS} -lhoard"
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_attr_setstacksize in LIBS=$LIBS with CFLAGS=$CFLAGS" >&5
$as_echo_n "checking for pthread_attr_setstacksize in LIBS=$LIBS with CFLAGS=$CFLAGS... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char pthread_attr_setstacksize ();
int
main ()
{
return pthread_attr_setstacksize ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
CFLAGS="${CFLAGS} -DNEED_STACK"
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: OK" >&5
$as_echo "OK" >&6; }
{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking for header files ***" >&5
$as_echo "$as_me: *** Checking for header files ***" >&6;}
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
if ${ac_cv_prog_CPP+:} false; then :
$as_echo_n "(cached) " >&6
else
# Double quotes because CPP needs to be expanded
for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
do
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# Prefer to if __STDC__ is defined, since
# exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __STDC__
# include
#else
# include
#endif
Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
else
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
# Broken: success on invalid input.
continue
else
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
break
fi
done
ac_cv_prog_CPP=$CPP
fi
CPP=$ac_cv_prog_CPP
else
ac_cv_prog_CPP=$CPP
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
# Use a header file that comes with gcc, so configuring glibc
# with a fresh cross-compiler works.
# Prefer to if __STDC__ is defined, since
# exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __STDC__
# include
#else
# include
#endif
Syntax error
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
else
# Broken: fails on valid input.
continue
fi
rm -f conftest.err conftest.i conftest.$ac_ext
# OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if ac_fn_c_try_cpp "$LINENO"; then :
# Broken: success on invalid input.
continue
else
# Passes both tests.
ac_preproc_ok=:
break
fi
rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
rm -f conftest.i conftest.err conftest.$ac_ext
if $ac_preproc_ok; then :
else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
if ${ac_cv_path_GREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if test -z "$GREP"; then
ac_path_GREP_found=false
# Loop through the user's path and test for each of PROGNAME-LIST
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_prog in grep ggrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
as_fn_executable_p "$ac_path_GREP" || continue
# Check for GNU ac_path_GREP and select it if it is found.
# Check for GNU $ac_path_GREP
case `"$ac_path_GREP" --version 2>&1` in
*GNU*)
ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
*)
ac_count=0
$as_echo_n 0123456789 >"conftest.in"
while :
do
cat "conftest.in" "conftest.in" >"conftest.tmp"
mv "conftest.tmp" "conftest.in"
cp "conftest.in" "conftest.nl"
$as_echo 'GREP' >> "conftest.nl"
"$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
as_fn_arith $ac_count + 1 && ac_count=$as_val
if test $ac_count -gt ${ac_path_GREP_max-0}; then
# Best one so far, save it but keep looking for a better one
ac_cv_path_GREP="$ac_path_GREP"
ac_path_GREP_max=$ac_count
fi
# 10*(2^10) chars as input seems more than enough
test $ac_count -gt 10 && break
done
rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac
$ac_path_GREP_found && break 3
done
done
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_GREP"; then
as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_GREP=$GREP
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
$as_echo "$ac_cv_path_GREP" >&6; }
GREP="$ac_cv_path_GREP"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
$as_echo_n "checking for egrep... " >&6; }
if ${ac_cv_path_EGREP+:} false; then :
$as_echo_n "(cached) " >&6
else
if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
then ac_cv_path_EGREP="$GREP -E"
else
if test -z "$EGREP"; then
ac_path_EGREP_found=false
# Loop through the user's path and test for each of PROGNAME-LIST
as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
for ac_prog in egrep; do
for ac_exec_ext in '' $ac_executable_extensions; do
ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
as_fn_executable_p "$ac_path_EGREP" || continue
# Check for GNU ac_path_EGREP and select it if it is found.
# Check for GNU $ac_path_EGREP
case `"$ac_path_EGREP" --version 2>&1` in
*GNU*)
ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
*)
ac_count=0
$as_echo_n 0123456789 >"conftest.in"
while :
do
cat "conftest.in" "conftest.in" >"conftest.tmp"
mv "conftest.tmp" "conftest.in"
cp "conftest.in" "conftest.nl"
$as_echo 'EGREP' >> "conftest.nl"
"$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
as_fn_arith $ac_count + 1 && ac_count=$as_val
if test $ac_count -gt ${ac_path_EGREP_max-0}; then
# Best one so far, save it but keep looking for a better one
ac_cv_path_EGREP="$ac_path_EGREP"
ac_path_EGREP_max=$ac_count
fi
# 10*(2^10) chars as input seems more than enough
test $ac_count -gt 10 && break
done
rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac
$ac_path_EGREP_found && break 3
done
done
done
IFS=$as_save_IFS
if test -z "$ac_cv_path_EGREP"; then
as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
fi
else
ac_cv_path_EGREP=$EGREP
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
$as_echo "$ac_cv_path_EGREP" >&6; }
EGREP="$ac_cv_path_EGREP"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
$as_echo_n "checking for ANSI C header files... " >&6; }
if ${ac_cv_header_stdc+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
#include
#include
int
main ()
{
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_header_stdc=yes
else
ac_cv_header_stdc=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "memchr" >/dev/null 2>&1; then :
else
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "free" >/dev/null 2>&1; then :
else
ac_cv_header_stdc=no
fi
rm -f conftest*
fi
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
if test "$cross_compiling" = yes; then :
:
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
#else
# define ISLOWER(c) \
(('a' <= (c) && (c) <= 'i') \
|| ('j' <= (c) && (c) <= 'r') \
|| ('s' <= (c) && (c) <= 'z'))
# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
#endif
#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
int
main ()
{
int i;
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
|| toupper (i) != TOUPPER (i))
return 2;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
else
ac_cv_header_stdc=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
$as_echo "$ac_cv_header_stdc" >&6; }
if test $ac_cv_header_stdc = yes; then
$as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
# On IRIX 5.3, sys/types and inttypes.h are conflicting.
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
for ac_header in arpa/inet.h errno.h netdb.h netinet/in.h netinet/tcp.h stdlib.h string.h sys/socket.h sys/un.h sys/time.h unistd.h getopt.h pthread.h sys/types.h sys/poll.h openssl/ssl.h openssl/engine.h time.h pwd.h grp.h signal.h regex.h ctype.h wait.h sys/wait.h sys/stat.h fcntl.h stdarg.h pcreposix.h pcre/pcreposix.h fnmatch.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: *** Checking for additonal information ***" >&5
$as_echo "$as_me: *** Checking for additonal information ***" >&6;}
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -DSYSLOG_NAMES=1"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for facilitynames presence" >&5
$as_echo_n "checking for facilitynames presence... " >&6; }
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
int
main ()
{
void *attr=(void *)facilitynames;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ok=yes
else
ok=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test x"$ok" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$save_CFLAGS -DHAVE_SYSLOG_H=1"
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
int
main ()
{
void *attr=(void *)facilitynames;
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ok=yes
else
ok=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
if test x"$ok" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
CFLAGS="$save_CFLAGS -DHAVE_SYS_SYSLOG_H=1"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: missing" >&5
$as_echo "missing" >&6; }
CFLAGS="$save_CFLAGS -DHAVE_SYSLOG_H=1 -DMISS_FACILITYNAMES"
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
$as_echo_n "checking return type of signal handlers... " >&6; }
if ${ac_cv_type_signal+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
int
main ()
{
return *(signal (0, 0)) (0) == 1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_type_signal=int
else
ac_cv_type_signal=void
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
$as_echo "$ac_cv_type_signal" >&6; }
cat >>confdefs.h <<_ACEOF
#define RETSIGTYPE $ac_cv_type_signal
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
$as_echo_n "checking for an ANSI C-conforming const... " >&6; }
if ${ac_cv_c_const+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
#ifndef __cplusplus
/* Ultrix mips cc rejects this sort of thing. */
typedef int charset[2];
const charset cs = { 0, 0 };
/* SunOS 4.1.1 cc rejects this. */
char const *const *pcpcc;
char **ppc;
/* NEC SVR4.0.2 mips cc rejects this. */
struct point {int x, y;};
static struct point const zero = {0,0};
/* AIX XL C 1.02.0.0 rejects this.
It does not let you subtract one const X* pointer from another in
an arm of an if-expression whose if-part is not a constant
expression */
const char *g = "string";
pcpcc = &g + (g ? g-g : 0);
/* HPUX 7.0 cc rejects these. */
++pcpcc;
ppc = (char**) pcpcc;
pcpcc = (char const *const *) ppc;
{ /* SCO 3.2v4 cc rejects this sort of thing. */
char tx;
char *t = &tx;
char const *s = 0 ? (char *) 0 : (char const *) 0;
*t++ = 0;
if (s) return 0;
}
{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
int x[] = {25, 17};
const int *foo = &x[0];
++foo;
}
{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
typedef const int *iptr;
iptr p = 0;
++p;
}
{ /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
"k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
struct s { int j; const int *ap[3]; } bx;
struct s *b = &bx; b->j = 5;
}
{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
const int foo = 10;
if (!foo) return 0;
}
return !cs[0] && !zero.x;
#endif
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_c_const=yes
else
ac_cv_c_const=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_const" >&5
$as_echo "$ac_cv_c_const" >&6; }
if test $ac_cv_c_const = no; then
$as_echo "#define const /**/" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
if ${ac_cv_type_uid_t+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
$EGREP "uid_t" >/dev/null 2>&1; then :
ac_cv_type_uid_t=yes
else
ac_cv_type_uid_t=no
fi
rm -f conftest*
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
$as_echo "$ac_cv_type_uid_t" >&6; }
if test $ac_cv_type_uid_t = no; then
$as_echo "#define uid_t int" >>confdefs.h
$as_echo "#define gid_t int" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
if test "x$ac_cv_type_pid_t" = xyes; then :
else
cat >>confdefs.h <<_ACEOF
#define pid_t int
_ACEOF
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
if ${ac_cv_header_time+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
#include
int
main ()
{
if ((struct tm *) 0)
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_header_time=yes
else
ac_cv_header_time=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
$as_echo "$ac_cv_header_time" >&6; }
if test $ac_cv_header_time = yes; then
$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for unsigned long long int" >&5
$as_echo_n "checking for unsigned long long int... " >&6; }
if ${ac_cv_type_unsigned_long_long_int+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_type_unsigned_long_long_int=yes
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* For now, do not test the preprocessor; as of 2007 there are too many
implementations with broken preprocessors. Perhaps this can
be revisited in 2012. In the meantime, code should not expect
#if to work with literals wider than 32 bits. */
/* Test literals. */
long long int ll = 9223372036854775807ll;
long long int nll = -9223372036854775807LL;
unsigned long long int ull = 18446744073709551615ULL;
/* Test constant expressions. */
typedef int a[((-9223372036854775807LL < 0 && 0 < 9223372036854775807ll)
? 1 : -1)];
typedef int b[(18446744073709551615ULL <= (unsigned long long int) -1
? 1 : -1)];
int i = 63;
int
main ()
{
/* Test availability of runtime routines for shift and division. */
long long int llmax = 9223372036854775807ll;
unsigned long long int ullmax = 18446744073709551615ull;
return ((ll << 63) | (ll >> 63) | (ll < i) | (ll > i)
| (llmax / ll) | (llmax % ll)
| (ull << 63) | (ull >> 63) | (ull << i) | (ull >> i)
| (ullmax / ull) | (ullmax % ull));
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
else
ac_cv_type_unsigned_long_long_int=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_unsigned_long_long_int" >&5
$as_echo "$ac_cv_type_unsigned_long_long_int" >&6; }
if test $ac_cv_type_unsigned_long_long_int = yes; then
$as_echo "#define HAVE_UNSIGNED_LONG_LONG_INT 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for long long int" >&5
$as_echo_n "checking for long long int... " >&6; }
if ${ac_cv_type_long_long_int+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_cv_type_long_long_int=yes
if test "x${ac_cv_prog_cc_c99-no}" = xno; then
ac_cv_type_long_long_int=$ac_cv_type_unsigned_long_long_int
if test $ac_cv_type_long_long_int = yes; then
if test "$cross_compiling" = yes; then :
:
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#ifndef LLONG_MAX
# define HALF \
(1LL << (sizeof (long long int) * CHAR_BIT - 2))
# define LLONG_MAX (HALF - 1 + HALF)
#endif
int
main ()
{
long long int n = 1;
int i;
for (i = 0; ; i++)
{
long long int m = n << i;
if (m >> i != n)
return 1;
if (LLONG_MAX / 2 < m)
break;
}
return 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
else
ac_cv_type_long_long_int=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_long_long_int" >&5
$as_echo "$ac_cv_type_long_long_int" >&6; }
if test $ac_cv_type_long_long_int = yes; then
$as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
fi
ac_fn_c_check_type "$LINENO" "in_addr_t" "ac_cv_type_in_addr_t" "#include
#include
"
if test "x$ac_cv_type_in_addr_t" = xyes; then :
else
CFLAGS="${CFLAGS} -DNEED_INADDRT"
fi
ac_fn_c_check_type "$LINENO" "in_port_t" "ac_cv_type_in_port_t" "#include
#include
"
if test "x$ac_cv_type_in_port_t" = xyes; then :
else
CFLAGS="${CFLAGS} -DNEED_INPORTT"
fi
ac_fn_c_check_type "$LINENO" "time_t" "ac_cv_type_time_t" "#include
"
if test "x$ac_cv_type_time_t" = xyes; then :
else
CFLAGS="${CFLAGS} -DNEED_TIMET"
fi
for ac_header in vfork.h
do :
ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
if test "x$ac_cv_header_vfork_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_VFORK_H 1
_ACEOF
fi
done
for ac_func in fork vfork
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
if test "x$ac_cv_func_fork" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working fork" >&5
$as_echo_n "checking for working fork... " >&6; }
if ${ac_cv_func_fork_works+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
ac_cv_func_fork_works=cross
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
/* By Ruediger Kuhlmann. */
return fork () < 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_fork_works=yes
else
ac_cv_func_fork_works=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_fork_works" >&5
$as_echo "$ac_cv_func_fork_works" >&6; }
else
ac_cv_func_fork_works=$ac_cv_func_fork
fi
if test "x$ac_cv_func_fork_works" = xcross; then
case $host in
*-*-amigaos* | *-*-msdosdjgpp*)
# Override, as these systems have only a dummy fork() stub
ac_cv_func_fork_works=no
;;
*)
ac_cv_func_fork_works=yes
;;
esac
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&5
$as_echo "$as_me: WARNING: result $ac_cv_func_fork_works guessed because of cross compilation" >&2;}
fi
ac_cv_func_vfork_works=$ac_cv_func_vfork
if test "x$ac_cv_func_vfork" = xyes; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working vfork" >&5
$as_echo_n "checking for working vfork... " >&6; }
if ${ac_cv_func_vfork_works+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
ac_cv_func_vfork_works=cross
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Thanks to Paul Eggert for this test. */
$ac_includes_default
#include
#ifdef HAVE_VFORK_H
# include
#endif
/* On some sparc systems, changes by the child to local and incoming
argument registers are propagated back to the parent. The compiler
is told about this with #include , but some compilers
(e.g. gcc -O) don't grok . Test for this by using a
static variable whose address is put into a register that is
clobbered by the vfork. */
static void
#ifdef __cplusplus
sparc_address_test (int arg)
# else
sparc_address_test (arg) int arg;
#endif
{
static pid_t child;
if (!child) {
child = vfork ();
if (child < 0) {
perror ("vfork");
_exit(2);
}
if (!child) {
arg = getpid();
write(-1, "", 0);
_exit (arg);
}
}
}
int
main ()
{
pid_t parent = getpid ();
pid_t child;
sparc_address_test (0);
child = vfork ();
if (child == 0) {
/* Here is another test for sparc vfork register problems. This
test uses lots of local variables, at least as many local
variables as main has allocated so far including compiler
temporaries. 4 locals are enough for gcc 1.40.3 on a Solaris
4.1.3 sparc, but we use 8 to be safe. A buggy compiler should
reuse the register of parent for one of the local variables,
since it will think that parent can't possibly be used any more
in this routine. Assigning to the local variable will thus
munge parent in the parent process. */
pid_t
p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
/* Convince the compiler that p..p7 are live; otherwise, it might
use the same hardware register for all 8 local variables. */
if (p != p1 || p != p2 || p != p3 || p != p4
|| p != p5 || p != p6 || p != p7)
_exit(1);
/* On some systems (e.g. IRIX 3.3), vfork doesn't separate parent
from child file descriptors. If the child closes a descriptor
before it execs or exits, this munges the parent's descriptor
as well. Test for this by closing stdout in the child. */
_exit(close(fileno(stdout)) != 0);
} else {
int status;
struct stat st;
while (wait(&status) != child)
;
return (
/* Was there some problem with vforking? */
child < 0
/* Did the child fail? (This shouldn't happen.) */
|| status
/* Did the vfork/compiler bug occur? */
|| parent != getpid()
/* Did the file descriptor bug occur? */
|| fstat(fileno(stdout), &st) != 0
);
}
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_vfork_works=yes
else
ac_cv_func_vfork_works=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_vfork_works" >&5
$as_echo "$ac_cv_func_vfork_works" >&6; }
fi;
if test "x$ac_cv_func_fork_works" = xcross; then
ac_cv_func_vfork_works=$ac_cv_func_vfork
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&5
$as_echo "$as_me: WARNING: result $ac_cv_func_vfork_works guessed because of cross compilation" >&2;}
fi
if test "x$ac_cv_func_vfork_works" = xyes; then
$as_echo "#define HAVE_WORKING_VFORK 1" >>confdefs.h
else
$as_echo "#define vfork fork" >>confdefs.h
fi
if test "x$ac_cv_func_fork_works" = xyes; then
$as_echo "#define HAVE_WORKING_FORK 1" >>confdefs.h
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
$as_echo_n "checking for working memcmp... " >&6; }
if ${ac_cv_func_memcmp_working+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
ac_cv_func_memcmp_working=no
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
/* Some versions of memcmp are not 8-bit clean. */
char c0 = '\100', c1 = '\200', c2 = '\201';
if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
return 1;
/* The Next x86 OpenStep bug shows up only when comparing 16 bytes
or more and with at least one buffer not starting on a 4-byte boundary.
William Lewis provided this test program. */
{
char foo[21];
char bar[21];
int i;
for (i = 0; i < 4; i++)
{
char *a = foo + i;
char *b = bar + i;
strcpy (a, "--------01111111");
strcpy (b, "--------10000000");
if (memcmp (a, b, 16) >= 0)
return 1;
}
return 0;
}
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_memcmp_working=yes
else
ac_cv_func_memcmp_working=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5
$as_echo "$ac_cv_func_memcmp_working" >&6; }
test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
*" memcmp.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
;;
esac
for ac_header in sys/select.h sys/socket.h
do :
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking types of arguments for select" >&5
$as_echo_n "checking types of arguments for select... " >&6; }
if ${ac_cv_func_select_args+:} false; then :
$as_echo_n "(cached) " >&6
else
for ac_arg234 in 'fd_set *' 'int *' 'void *'; do
for ac_arg1 in 'int' 'size_t' 'unsigned long int' 'unsigned int'; do
for ac_arg5 in 'struct timeval *' 'const struct timeval *'; do
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
#ifdef HAVE_SYS_SELECT_H
# include
#endif
#ifdef HAVE_SYS_SOCKET_H
# include
#endif
int
main ()
{
extern int select ($ac_arg1,
$ac_arg234, $ac_arg234, $ac_arg234,
$ac_arg5);
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_func_select_args="$ac_arg1,$ac_arg234,$ac_arg5"; break 3
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
done
done
done
# Provide a safe default value.
: "${ac_cv_func_select_args=int,int *,struct timeval *}"
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_select_args" >&5
$as_echo "$ac_cv_func_select_args" >&6; }
ac_save_IFS=$IFS; IFS=','
set dummy `echo "$ac_cv_func_select_args" | sed 's/\*/\*/g'`
IFS=$ac_save_IFS
shift
cat >>confdefs.h <<_ACEOF
#define SELECT_TYPE_ARG1 $1
_ACEOF
cat >>confdefs.h <<_ACEOF
#define SELECT_TYPE_ARG234 ($2)
_ACEOF
cat >>confdefs.h <<_ACEOF
#define SELECT_TYPE_ARG5 ($3)
_ACEOF
rm -f conftest*
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
$as_echo_n "checking return type of signal handlers... " >&6; }
if ${ac_cv_type_signal+:} false; then :
$as_echo_n "(cached) " >&6
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include
#include
int
main ()
{
return *(signal (0, 0)) (0) == 1;
;
return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_type_signal=int
else
ac_cv_type_signal=void
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_signal" >&5
$as_echo "$ac_cv_type_signal" >&6; }
cat >>confdefs.h <<_ACEOF
#define RETSIGTYPE $ac_cv_type_signal
_ACEOF
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether lstat correctly handles trailing slash" >&5
$as_echo_n "checking whether lstat correctly handles trailing slash... " >&6; }
if ${ac_cv_func_lstat_dereferences_slashed_symlink+:} false; then :
$as_echo_n "(cached) " >&6
else
rm -f conftest.sym conftest.file
echo >conftest.file
if test "$as_ln_s" = "ln -s" && ln -s conftest.file conftest.sym; then
if test "$cross_compiling" = yes; then :
ac_cv_func_lstat_dereferences_slashed_symlink=no
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
struct stat sbuf;
/* Linux will dereference the symlink and fail, as required by POSIX.
That is better in the sense that it means we will not
have to compile and use the lstat wrapper. */
return lstat ("conftest.sym/", &sbuf) == 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_lstat_dereferences_slashed_symlink=yes
else
ac_cv_func_lstat_dereferences_slashed_symlink=no
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
else
# If the `ln -s' command failed, then we probably don't even
# have an lstat function.
ac_cv_func_lstat_dereferences_slashed_symlink=no
fi
rm -f conftest.sym conftest.file
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_lstat_dereferences_slashed_symlink" >&5
$as_echo "$ac_cv_func_lstat_dereferences_slashed_symlink" >&6; }
test $ac_cv_func_lstat_dereferences_slashed_symlink = yes &&
cat >>confdefs.h <<_ACEOF
#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1
_ACEOF
if test "x$ac_cv_func_lstat_dereferences_slashed_symlink" = xno; then
case " $LIBOBJS " in
*" lstat.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS lstat.$ac_objext"
;;
esac
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stat accepts an empty string" >&5
$as_echo_n "checking whether stat accepts an empty string... " >&6; }
if ${ac_cv_func_stat_empty_string_bug+:} false; then :
$as_echo_n "(cached) " >&6
else
if test "$cross_compiling" = yes; then :
ac_cv_func_stat_empty_string_bug=yes
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
struct stat sbuf;
return stat ("", &sbuf) == 0;
;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_stat_empty_string_bug=no
else
ac_cv_func_stat_empty_string_bug=yes
fi
rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_stat_empty_string_bug" >&5
$as_echo "$ac_cv_func_stat_empty_string_bug" >&6; }
if test $ac_cv_func_stat_empty_string_bug = yes; then
case " $LIBOBJS " in
*" stat.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS stat.$ac_objext"
;;
esac
cat >>confdefs.h <<_ACEOF
#define HAVE_STAT_EMPTY_STRING_BUG 1
_ACEOF
fi
for ac_func in strftime
do :
ac_fn_c_check_func "$LINENO" "strftime" "ac_cv_func_strftime"
if test "x$ac_cv_func_strftime" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRFTIME 1
_ACEOF
else
# strftime is in -lintl on SCO UNIX.
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for strftime in -lintl" >&5
$as_echo_n "checking for strftime in -lintl... " >&6; }
if ${ac_cv_lib_intl_strftime+:} false; then :
$as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lintl $LIBS"
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char strftime ();
int
main ()
{
return strftime ();
;
return 0;
}
_ACEOF
if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_intl_strftime=yes
else
ac_cv_lib_intl_strftime=no
fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_intl_strftime" >&5
$as_echo "$ac_cv_lib_intl_strftime" >&6; }
if test "x$ac_cv_lib_intl_strftime" = xyes; then :
$as_echo "#define HAVE_STRFTIME 1" >>confdefs.h
LIBS="-lintl $LIBS"
fi
fi
done
for ac_func in getaddrinfo inet_ntop memset regcomp poll socket strcasecmp strchr strdup strerror strncasecmp strspn strtol setsid X509_STORE_set_flags localtime_r gettimeofday
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
if test -z "${I_OWNER}"
then
egrep -s '^root' /etc/passwd > /dev/null && I_OWNER=root
egrep -s '^sys' /etc/passwd > /dev/null && I_OWNER=sys
egrep -s '^bin' /etc/passwd > /dev/null && I_OWNER=bin
egrep -s '^daemon' /etc/passwd > /dev/null && I_OWNER=daemon
egrep -s '^www' /etc/passwd > /dev/null && I_OWNER=www
egrep -s '^proxy' /etc/passwd > /dev/null && I_OWNER=proxy
fi
if test -z "${I_GRP}"
then
egrep -s '^root' /etc/group > /dev/null && I_GRP=root
egrep -s '^sys' /etc/group > /dev/null && I_GRP=sys
egrep -s '^bin' /etc/group > /dev/null && I_GRP=bin
egrep -s '^daemon' /etc/group > /dev/null && I_GRP=daemon
egrep -s '^www' /etc/group > /dev/null && I_GRP=www
egrep -s '^proxy' /etc/group > /dev/null && I_GRP=proxy
fi
ac_config_files="$ac_config_files Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
# tests run on this system so they can be shared between configure
# scripts and configure runs, see configure's option --config-cache.
# It is not useful on other systems. If it contains results you don't
# want to keep, you may remove or edit it.
#
# config.status only pays attention to the cache file if you give it
# the --recheck option to rerun configure.
#
# `ac_cv_env_foo' variables (set or unset) will be overridden when
# loading this file, other *unset* `ac_cv_foo' will be assigned the
# following values.
_ACEOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
(
for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
eval ac_val=\$$ac_var
case $ac_val in #(
*${as_nl}*)
case $ac_var in #(
*_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
esac
case $ac_var in #(
_ | IFS | as_nl) ;; #(
BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
*) { eval $ac_var=; unset $ac_var;} ;;
esac ;;
esac
done
(set) 2>&1 |
case $as_nl`(ac_space=' '; set) 2>&1` in #(
*${as_nl}ac_space=\ *)
# `set' does not quote correctly, so add quotes: double-quote
# substitution turns \\\\ into \\, and sed turns \\ into \.
sed -n \
"s/'/'\\\\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
;; #(
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
esac |
sort
) |
sed '
/^ac_cv_env_/b end
t clear
:clear
s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
t end
s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
:end' >>confcache
if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
if test -w "$cache_file"; then
if test "x$cache_file" != "x/dev/null"; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
$as_echo "$as_me: updating cache $cache_file" >&6;}
if test ! -f "$cache_file" || test -h "$cache_file"; then
cat confcache >"$cache_file"
else
case $cache_file in #(
*/* | ?:*)
mv -f confcache "$cache_file"$$ &&
mv -f "$cache_file"$$ "$cache_file" ;; #(
*)
mv -f confcache "$cache_file" ;;
esac
fi
fi
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
fi
fi
rm -f confcache
test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
DEFS=-DHAVE_CONFIG_H
ac_libobjs=
ac_ltlibobjs=
U=
for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
# 1. Remove the extension, and $U if already installed.
ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
# 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
# will be set to the directory where LIBOBJS objects are built.
as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
done
LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
: "${CONFIG_STATUS=./config.status}"
ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
as_write_fail=0
cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
# Compiler output produced by configure, useful for debugging
# configure, is in config.log if it exists.
debug=false
ac_cs_recheck=false
ac_cs_silent=false
SHELL=\${CONFIG_SHELL-$SHELL}
export SHELL
_ASEOF
cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
## -------------------- ##
## M4sh Initialization. ##
## -------------------- ##
# Be more Bourne compatible
DUALCASE=1; export DUALCASE # for MKS sh
if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
# Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
setopt NO_GLOB_SUBST
else
case `(set -o) 2>/dev/null` in #(
*posix*) :
set -o posix ;; #(
*) :
;;
esac
fi
as_nl='
'
export as_nl
# Printing a long string crashes Solaris 7 /usr/bin/printf.
as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
# Prefer a ksh shell builtin over an external printf program on Solaris,
# but without wasting forks for bash or zsh.
if test -z "$BASH_VERSION$ZSH_VERSION" \
&& (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='print -r --'
as_echo_n='print -rn --'
elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
as_echo='printf %s\n'
as_echo_n='printf %s'
else
if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
as_echo_n='/usr/ucb/echo -n'
else
as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
as_echo_n_body='eval
arg=$1;
case $arg in #(
*"$as_nl"*)
expr "X$arg" : "X\\(.*\\)$as_nl";
arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
esac;
expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
'
export as_echo_n_body
as_echo_n='sh -c $as_echo_n_body as_echo'
fi
export as_echo_body
as_echo='sh -c $as_echo_body as_echo'
fi
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
# IFS
# We need space, tab and new line, in precisely that order. Quoting is
# there to prevent editors from complaining about space-tab.
# (If _AS_PATH_WALK were called with IFS unset, it would disable word
# splitting by setting IFS to empty value.)
IFS=" "" $as_nl"
# Find who we are. Look in the path if we contain no directory separator.
as_myself=
case $0 in #((
*[\\/]* ) as_myself=$0 ;;
*) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
done
IFS=$as_save_IFS
;;
esac
# We did not find ourselves, most probably we were run as `sh COMMAND'
# in which case we are not to be found in the path.
if test "x$as_myself" = x; then
as_myself=$0
fi
if test ! -f "$as_myself"; then
$as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
exit 1
fi
# Unset variables that we do not need and which cause bugs (e.g. in
# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
# suppresses any "Segmentation fault" message there. '((' could
# trigger a bug in pdksh 5.2.14.
for as_var in BASH_ENV ENV MAIL MAILPATH
do eval test x\${$as_var+set} = xset \
&& ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
LC_ALL=C
export LC_ALL
LANGUAGE=C
export LANGUAGE
# CDPATH.
(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
# as_fn_error STATUS ERROR [LINENO LOG_FD]
# ----------------------------------------
# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
# script with STATUS, using 1 if that was 0.
as_fn_error ()
{
as_status=$1; test $as_status -eq 0 && as_status=1
if test "$4"; then
as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
$as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
$as_echo "$as_me: error: $2" >&2
as_fn_exit $as_status
} # as_fn_error
# as_fn_set_status STATUS
# -----------------------
# Set $? to STATUS, without forking.
as_fn_set_status ()
{
return $1
} # as_fn_set_status
# as_fn_exit STATUS
# -----------------
# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
as_fn_exit ()
{
set +e
as_fn_set_status $1
exit $1
} # as_fn_exit
# as_fn_unset VAR
# ---------------
# Portably unset VAR.
as_fn_unset ()
{
{ eval $1=; unset $1;}
}
as_unset=as_fn_unset
# as_fn_append VAR VALUE
# ----------------------
# Append the text in VALUE to the end of the definition contained in VAR. Take
# advantage of any shell optimizations that allow amortized linear growth over
# repeated appends, instead of the typical quadratic growth present in naive
# implementations.
if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
eval 'as_fn_append ()
{
eval $1+=\$2
}'
else
as_fn_append ()
{
eval $1=\$$1\$2
}
fi # as_fn_append
# as_fn_arith ARG...
# ------------------
# Perform arithmetic evaluation on the ARGs, and store the result in the
# global $as_val. Take advantage of shells that can avoid forks. The arguments
# must be portable across $(()) and expr.
if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
eval 'as_fn_arith ()
{
as_val=$(( $* ))
}'
else
as_fn_arith ()
{
as_val=`expr "$@" || test $? -eq 1`
}
fi # as_fn_arith
if expr a : '\(a\)' >/dev/null 2>&1 &&
test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
as_dirname=dirname
else
as_dirname=false
fi
as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
X"$0" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X/"$0" |
sed '/^.*\/\([^/][^/]*\)\/*$/{
s//\1/
q
}
/^X\/\(\/\/\)$/{
s//\1/
q
}
/^X\/\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
ECHO_C= ECHO_N= ECHO_T=
case `echo -n x` in #(((((
-n*)
case `echo 'xy\c'` in
*c*) ECHO_T=' ';; # ECHO_T is single tab character.
xy) ECHO_C='\c';;
*) echo `echo ksh88 bug on AIX 6.1` > /dev/null
ECHO_T=' ';;
esac;;
*)
ECHO_N='-n';;
esac
rm -f conf$$ conf$$.exe conf$$.file
if test -d conf$$.dir; then
rm -f conf$$.dir/conf$$.file
else
rm -f conf$$.dir
mkdir conf$$.dir 2>/dev/null
fi
if (echo >conf$$.file) 2>/dev/null; then
if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
# ... but there are two gotchas:
# 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
# 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
# In both cases, we have to default to `cp -pR'.
ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
as_ln_s='cp -pR'
elif ln conf$$.file conf$$ 2>/dev/null; then
as_ln_s=ln
else
as_ln_s='cp -pR'
fi
else
as_ln_s='cp -pR'
fi
rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
rmdir conf$$.dir 2>/dev/null
# as_fn_mkdir_p
# -------------
# Create "$as_dir" as a directory, including parents if necessary.
as_fn_mkdir_p ()
{
case $as_dir in #(
-*) as_dir=./$as_dir;;
esac
test -d "$as_dir" || eval $as_mkdir_p || {
as_dirs=
while :; do
case $as_dir in #(
*\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
*) as_qdir=$as_dir;;
esac
as_dirs="'$as_qdir' $as_dirs"
as_dir=`$as_dirname -- "$as_dir" ||
$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$as_dir" : 'X\(//\)[^/]' \| \
X"$as_dir" : 'X\(//\)$' \| \
X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$as_dir" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
test -d "$as_dir" && break
done
test -z "$as_dirs" || eval "mkdir $as_dirs"
} || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
# as_fn_executable_p FILE
# -----------------------
# Test if FILE is an executable regular file.
as_fn_executable_p ()
{
test -f "$1" && test -x "$1"
} # as_fn_executable_p
as_test_x='test -x'
as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
# Sed expression to map a string onto a valid variable name.
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
exec 6>&1
## ----------------------------------- ##
## Main body of $CONFIG_STATUS script. ##
## ----------------------------------- ##
_ASEOF
test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by pound $as_me 2.8, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
CONFIG_LINKS = $CONFIG_LINKS
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
on `(hostname || uname -n) 2>/dev/null | sed 1q`
"
_ACEOF
case $ac_config_files in *"
"*) set x $ac_config_files; shift; ac_config_files=$*;;
esac
case $ac_config_headers in *"
"*) set x $ac_config_headers; shift; ac_config_headers=$*;;
esac
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
# Files that config.status was made for.
config_files="$ac_config_files"
config_headers="$ac_config_headers"
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
\`$as_me' instantiates files and other configuration actions
from templates according to the current configuration. Unless the files
and actions are specified as TAGs, all are instantiated by default.
Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
-V, --version print version number and configuration settings, then exit
--config print configuration, then exit
-q, --quiet, --silent
do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
--file=FILE[:TEMPLATE]
instantiate the configuration file FILE
--header=FILE[:TEMPLATE]
instantiate the configuration header FILE
Configuration files:
$config_files
Configuration headers:
$config_headers
Report bugs to ."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
pound config.status 2.8
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
ac_pwd='$ac_pwd'
srcdir='$srcdir'
INSTALL='$INSTALL'
test -n "\$AWK" || AWK=awk
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
--*=?*)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
--*=)
ac_option=`expr "X$1" : 'X\([^=]*\)='`
ac_optarg=
ac_shift=:
;;
*)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
esac
case $ac_option in
# Handling of the options.
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
--version | --versio | --versi | --vers | --ver | --ve | --v | -V )
$as_echo "$ac_cs_version"; exit ;;
--config | --confi | --conf | --con | --co | --c )
$as_echo "$ac_cs_config"; exit ;;
--debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
'') as_fn_error $? "missing file argument" ;;
esac
as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
--header | --heade | --head | --hea )
$ac_shift
case $ac_optarg in
*\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
as_fn_append CONFIG_HEADERS " '$ac_optarg'"
ac_need_defaults=false;;
--he | --h)
# Conflict between --help and --header
as_fn_error $? "ambiguous option: \`$1'
Try \`$0 --help' for more information.";;
--help | --hel | -h )
$as_echo "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
# This is an error.
-*) as_fn_error $? "unrecognized option: \`$1'
Try \`$0 --help' for more information." ;;
*) as_fn_append ac_config_targets " $1"
ac_need_defaults=false ;;
esac
shift
done
ac_configure_extra_args=
if $ac_cs_silent; then
exec 6>/dev/null
ac_configure_extra_args="$ac_configure_extra_args --silent"
fi
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
shift
\$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
CONFIG_SHELL='$SHELL'
export CONFIG_SHELL
exec "\$@"
fi
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
exec 5>>config.log
{
echo
sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
## Running $as_me. ##
_ASBOX
$as_echo "$ac_log"
} >&5
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# Handling of arguments.
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
*) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
# bizarre bug on SunOS 4.1.3.
if $ac_need_defaults; then
test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
fi
# Have a temporary directory for convenience. Make it in the build tree
# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
# Hook for its removal unless debugging.
# Note that there is a small window in which the directory will not be cleaned:
# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
tmp= ac_tmp=
trap 'exit_status=$?
: "${ac_tmp:=$tmp}"
{ test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
' 0
trap 'as_fn_exit 1' 1 2 13 15
}
# Create a (secure) tmp directory for tmp files.
{
tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
test -d "$tmp"
} ||
{
tmp=./conf$$-$RANDOM
(umask 077 && mkdir "$tmp")
} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
ac_tmp=$tmp
# Set up the scripts for CONFIG_FILES section.
# No need to generate them if there are no CONFIG_FILES.
# This happens for instance with `./config.status config.h'.
if test -n "$CONFIG_FILES"; then
ac_cr=`echo X | tr X '\015'`
# On cygwin, bash can eat \r inside `` if the user requested igncr.
# But we know of no other shell where ac_cr would be empty at this
# point, so we can use a bashism as a fallback.
if test "x$ac_cr" = x; then
eval ac_cr=\$\'\\r\'
fi
ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null`
if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
ac_cs_awk_cr='\\r'
else
ac_cs_awk_cr=$ac_cr
fi
echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
_ACEOF
{
echo "cat >conf$$subs.awk <<_ACEOF" &&
echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
echo "_ACEOF"
} >conf$$subs.sh ||
as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
. ./conf$$subs.sh ||
as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
if test $ac_delim_n = $ac_delim_num; then
break
elif $ac_last_try; then
as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
done
rm -f conf$$subs.sh
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
_ACEOF
sed -n '
h
s/^/S["/; s/!.*/"]=/
p
g
s/^[^!]*!//
:repl
t repl
s/'"$ac_delim"'$//
t delim
:nl
h
s/\(.\{148\}\)..*/\1/
t more1
s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
p
n
b repl
:more1
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{148\}//
t nl
:delim
h
s/\(.\{148\}\)..*/\1/
t more2
s/["\\]/\\&/g; s/^/"/; s/$/"/
p
b
:more2
s/["\\]/\\&/g; s/^/"/; s/$/"\\/
p
g
s/.\{148\}//
t delim
' >$CONFIG_STATUS || ac_write_fail=1
rm -f conf$$subs.awk
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
_ACAWK
cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
for (key in S) S_is_set[key] = 1
FS = ""
}
{
line = $ 0
nfields = split(line, field, "@")
substed = 0
len = length(field[1])
for (i = 2; i < nfields; i++) {
key = field[i]
keylen = length(key)
if (S_is_set[key]) {
value = S[key]
line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
len += length(value) + length(field[++i])
substed = 1
} else
len += 1 + keylen
}
print line
}
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
else
cat
fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
|| as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
# trailing colons and then remove the whole line if VPATH becomes empty
# (actually we leave an empty line to preserve line numbers).
if test "x$srcdir" = x.; then
ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
h
s///
s/^/:/
s/[ ]*$/:/
s/:\$(srcdir):/:/g
s/:\${srcdir}:/:/g
s/:@srcdir@:/:/g
s/^:*//
s/:*$//
x
s/\(=[ ]*\).*/\1/
G
s/\n//
s/^[^=]*=[ ]*$//
}'
fi
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
fi # test -n "$CONFIG_FILES"
# Set up the scripts for CONFIG_HEADERS section.
# No need to generate them if there are no CONFIG_HEADERS.
# This happens for instance with `./config.status Makefile'.
if test -n "$CONFIG_HEADERS"; then
cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
BEGIN {
_ACEOF
# Transform confdefs.h into an awk script `defines.awk', embedded as
# here-document in config.status, that substitutes the proper values into
# config.h.in to produce config.h.
# Create a delimiter string that does not exist in confdefs.h, to ease
# handling of long lines.
ac_delim='%!_!# '
for ac_last_try in false false :; do
ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
if test -z "$ac_tt"; then
break
elif $ac_last_try; then
as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
else
ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
fi
done
# For the awk script, D is an array of macro values keyed by name,
# likewise P contains macro parameters if any. Preserve backslash
# newline sequences.
ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*
sed -n '
s/.\{148\}/&'"$ac_delim"'/g
t rset
:rset
s/^[ ]*#[ ]*define[ ][ ]*/ /
t def
d
:def
s/\\$//
t bsnl
s/["\\]/\\&/g
s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
D["\1"]=" \3"/p
s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p
d
:bsnl
s/["\\]/\\&/g
s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\
D["\1"]=" \3\\\\\\n"\\/p
t cont
s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p
t cont
d
:cont
n
s/.\{148\}/&'"$ac_delim"'/g
t clear
:clear
s/\\$//
t bsnlc
s/["\\]/\\&/g; s/^/"/; s/$/"/p
d
:bsnlc
s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p
b cont
' >$CONFIG_STATUS || ac_write_fail=1
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
for (key in D) D_is_set[key] = 1
FS = ""
}
/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {
line = \$ 0
split(line, arg, " ")
if (arg[1] == "#") {
defundef = arg[2]
mac1 = arg[3]
} else {
defundef = substr(arg[1], 2)
mac1 = arg[2]
}
split(mac1, mac2, "(") #)
macro = mac2[1]
prefix = substr(line, 1, index(line, defundef) - 1)
if (D_is_set[macro]) {
# Preserve the white space surrounding the "#".
print prefix "define", macro P[macro] D[macro]
next
} else {
# Replace #undef with comments. This is necessary, for example,
# in the case of _POSIX_SOURCE, which is predefined and required
# on some systems where configure will not decide to define it.
if (defundef == "undef") {
print "/*", prefix defundef, macro, "*/"
next
}
}
}
{ print }
_ACAWK
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
fi # test -n "$CONFIG_HEADERS"
eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS "
shift
for ac_tag
do
case $ac_tag in
:[FHLC]) ac_mode=$ac_tag; continue;;
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
:L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
ac_save_IFS=$IFS
IFS=:
set x $ac_tag
IFS=$ac_save_IFS
shift
ac_file=$1
shift
case $ac_mode in
:L) ac_source=$1;;
:[FH])
ac_file_inputs=
for ac_f
do
case $ac_f in
-) ac_f="$ac_tmp/stdin";;
*) # Look for the file first in the build tree, then in the source tree
# (if the path is not absolute). The absolute path cannot be DOS-style,
# because $ac_f cannot contain `:'.
test -f "$ac_f" ||
case $ac_f in
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
done
# Let's still pretend it is `configure' which instantiates (i.e., don't
# use $as_me), people would be surprised to read:
# /* config.h. Generated by config.status. */
configure_input='Generated from '`
$as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
`' by configure.'
if test x"$ac_file" != x-; then
configure_input="$ac_file. $configure_input"
{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
$as_echo "$as_me: creating $ac_file" >&6;}
fi
# Neutralize special characters interpreted by sed in replacement strings.
case $configure_input in #(
*\&* | *\|* | *\\* )
ac_sed_conf_input=`$as_echo "$configure_input" |
sed 's/[\\\\&|]/\\\\&/g'`;; #(
*) ac_sed_conf_input=$configure_input;;
esac
case $ac_tag in
*:-:* | *:-) cat >"$ac_tmp/stdin" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$ac_file" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`
as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
case "$ac_dir" in
.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
*)
ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
# A ".." for each directory in $ac_dir_suffix.
ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
case $ac_top_builddir_sub in
"") ac_top_builddir_sub=. ac_top_build_prefix= ;;
*) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
esac ;;
esac
ac_abs_top_builddir=$ac_pwd
ac_abs_builddir=$ac_pwd$ac_dir_suffix
# for backward compatibility:
ac_top_builddir=$ac_top_build_prefix
case $srcdir in
.) # We are building in place.
ac_srcdir=.
ac_top_srcdir=$ac_top_builddir_sub
ac_abs_top_srcdir=$ac_pwd ;;
[\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
ac_top_srcdir=$srcdir
ac_abs_top_srcdir=$srcdir ;;
*) # Relative name.
ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
ac_top_srcdir=$ac_top_build_prefix$srcdir
ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
case $ac_mode in
:F)
#
# CONFIG_FILE
#
case $INSTALL in
[\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
*) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
esac
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# If the template does not know about datarootdir, expand it.
# FIXME: This hack should be removed a few years after 2.60.
ac_datarootdir_hack=; ac_datarootdir_seen=
ac_sed_dataroot='
/datarootdir/ {
p
q
}
/@datadir@/p
/@docdir@/p
/@infodir@/p
/@localedir@/p
/@mandir@/p'
case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
*datarootdir*) ac_datarootdir_seen=yes;;
*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_datarootdir_hack='
s&@datadir@&$datadir&g
s&@docdir@&$docdir&g
s&@infodir@&$infodir&g
s&@localedir@&$localedir&g
s&@mandir@&$mandir&g
s&\\\${datarootdir}&$datarootdir&g' ;;
esac
_ACEOF
# Neutralize VPATH when `$srcdir' = `.'.
# Shell code in configure.ac might set extrasub.
# FIXME: do we really want to maintain this feature?
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
s|@configure_input@|$ac_sed_conf_input|;t t
s&@top_builddir@&$ac_top_builddir_sub&;t t
s&@top_build_prefix@&$ac_top_build_prefix&;t t
s&@srcdir@&$ac_srcdir&;t t
s&@abs_srcdir@&$ac_abs_srcdir&;t t
s&@top_srcdir@&$ac_top_srcdir&;t t
s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
s&@builddir@&$ac_builddir&;t t
s&@abs_builddir@&$ac_abs_builddir&;t t
s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
s&@INSTALL@&$ac_INSTALL&;t t
$ac_datarootdir_hack
"
eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
>$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
{ ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
{ ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
"$ac_tmp/out"`; test -z "$ac_out"; } &&
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&5
$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
which seems to be undefined. Please make sure it is defined" >&2;}
rm -f "$ac_tmp/stdin"
case $ac_file in
-) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
*) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
esac \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
;;
:H)
#
# CONFIG_HEADER
#
if test x"$ac_file" != x-; then
{
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
} >"$ac_tmp/config.h" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
$as_echo "$as_me: $ac_file is unchanged" >&6;}
else
rm -f "$ac_file"
mv "$ac_tmp/config.h" "$ac_file" \
|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
fi
else
$as_echo "/* $configure_input */" \
&& eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
|| as_fn_error $? "could not create -" "$LINENO" 5
fi
# Compute "$ac_file"'s index in $config_headers.
_am_arg="$ac_file"
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$_am_arg | $_am_arg:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $_am_arg" >`$as_dirname -- "$_am_arg" ||
$as_expr X"$_am_arg" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$_am_arg" : 'X\(//\)[^/]' \| \
X"$_am_arg" : 'X\(//\)$' \| \
X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
$as_echo X"$_am_arg" |
sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
s//\1/
q
}
/^X\(\/\/\)[^/].*/{
s//\1/
q
}
/^X\(\/\/\)$/{
s//\1/
q
}
/^X\(\/\).*/{
s//\1/
q
}
s/.*/./; q'`/stamp-h$_am_stamp_count
;;
esac
done # for ac_tag
as_fn_exit 0
_ACEOF
ac_clean_files=$ac_clean_files_save
test $ac_write_fail = 0 ||
as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
# Unfortunately, on DOS this fails, as config.log is still kept open
# by configure, so config.status won't be able to write to it; its
# output is simply discarded. So we exec the FD to /dev/null,
# effectively closing config.log, so it can be properly (re)opened and
# appended to by config.status. When coming back to configure, we
# need to make the FD available again.
if test "$no_create" != yes; then
ac_cs_success=:
ac_config_status_args=
test "$silent" = yes &&
ac_config_status_args="$ac_config_status_args --quiet"
exec 5>/dev/null
$SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
$ac_cs_success || as_fn_exit 1
fi
if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
Pound-2.8/config.c 0000664 0001750 0001750 00000216040 13275266545 013125 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#ifndef MISS_FACILITYNAMES
#define SYSLOG_NAMES 1
#endif
#include "pound.h"
#include
#ifdef MISS_FACILITYNAMES
/* This is lifted verbatim from the Linux sys/syslog.h */
typedef struct _code {
char *c_name;
int c_val;
} CODE;
static CODE facilitynames[] = {
{ "auth", LOG_AUTH },
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV },
#endif
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
#ifdef LOG_FTP
{ "ftp", LOG_FTP },
#endif
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "mark", 0 }, /* never used! */
{ "news", LOG_NEWS },
{ "security", LOG_AUTH }, /* DEPRECATED */
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
#endif
static regex_t Empty, Comment, User, Group, RootJail, Daemon, LogFacility, LogLevel, Alive, SSLEngine, Control;
static regex_t ListenHTTP, ListenHTTPS, End, Address, Port, Cert, xHTTP, Client, CheckURL;
static regex_t Err414, Err500, Err501, Err503, MaxRequest, HeadRemove, RewriteLocation, RewriteDestination;
static regex_t Service, ServiceName, URL, HeadRequire, HeadDeny, BackEnd, Emergency, Priority, HAport, HAportAddr;
static regex_t Redirect, RedirectN, TimeOut, Session, Type, TTL, ID;
static regex_t ClientCert, AddHeader, DisableProto, SSLAllowClientRenegotiation, SSLHonorCipherOrder, Ciphers;
static regex_t CAlist, VerifyList, CRLlist, NoHTTPS11, Grace, Include, ConnTO, IgnoreCase, HTTPS;
static regex_t Disabled, Threads, CNName, Anonymise, ECDHCurve;
static regmatch_t matches[5];
static char *xhttp[] = {
"^(GET|POST|HEAD) ([^ ]+) HTTP/1.[01]$",
"^(GET|POST|HEAD|PUT|PATCH|DELETE) ([^ ]+) HTTP/1.[01]$",
"^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT) ([^ ]+) HTTP/1.[01]$",
"^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT|SUBSCRIBE|UNSUBSCRIBE|BPROPPATCH|POLL|BMOVE|BCOPY|BDELETE|BPROPFIND|NOTIFY|CONNECT) ([^ ]+) HTTP/1.[01]$",
"^(GET|POST|HEAD|PUT|PATCH|DELETE|LOCK|UNLOCK|PROPFIND|PROPPATCH|SEARCH|MKCOL|MOVE|COPY|OPTIONS|TRACE|MKACTIVITY|CHECKOUT|MERGE|REPORT|SUBSCRIBE|UNSUBSCRIBE|BPROPPATCH|POLL|BMOVE|BCOPY|BDELETE|BPROPFIND|NOTIFY|CONNECT|RPC_IN_DATA|RPC_OUT_DATA) ([^ ]+) HTTP/1.[01]$",
};
static int log_level = 1;
static int def_facility = LOG_DAEMON;
static int clnt_to = 10;
static int be_to = 15;
static int be_connto = 15;
static int ignore_case = 0;
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
static int EC_nid = NID_X9_62_prime256v1;
#endif
#endif
#define MAX_FIN 8
static FILE *f_in[MAX_FIN];
static char *f_name[MAX_FIN];
static int n_lin[MAX_FIN];
static int cur_fin;
static int
conf_init(const char *name)
{
if((f_name[0] = strdup(name)) == NULL) {
logmsg(LOG_ERR, "open %s: out of memory", name);
exit(1);
}
if((f_in[0] = fopen(name, "rt")) == NULL) {
logmsg(LOG_ERR, "can't open open %s", name);
exit(1);
}
n_lin[0] = 0;
cur_fin = 0;
return 0;
}
void
conf_err(const char *msg)
{
logmsg(LOG_ERR, "%s line %d: %s", f_name[cur_fin], n_lin[cur_fin], msg);
exit(1);
}
static char *
conf_fgets(char *buf, const int max)
{
int i;
for(;;) {
if(fgets(buf, max, f_in[cur_fin]) == NULL) {
fclose(f_in[cur_fin]);
free(f_name[cur_fin]);
if(cur_fin > 0) {
cur_fin--;
continue;
} else
return NULL;
}
n_lin[cur_fin]++;
for(i = 0; i < max; i++)
if(buf[i] == '\n' || buf[i] == '\r') {
buf[i] = '\0';
break;
}
if(!regexec(&Empty, buf, 4, matches, 0) || !regexec(&Comment, buf, 4, matches, 0))
/* comment or empty line */
continue;
if(!regexec(&Include, buf, 4, matches, 0)) {
buf[matches[1].rm_eo] = '\0';
if(cur_fin == (MAX_FIN - 1))
conf_err("Include nesting too deep");
cur_fin++;
if((f_name[cur_fin] = strdup(&buf[matches[1].rm_so])) == NULL)
conf_err("Include out of memory");
if((f_in[cur_fin] = fopen(&buf[matches[1].rm_so], "rt")) == NULL)
conf_err("can't open included file");
n_lin[cur_fin] = 0;
continue;
}
return buf;
}
}
unsigned char **
get_subjectaltnames(X509 *x509, unsigned int *count)
{
unsigned int local_count;
unsigned char **result;
STACK_OF(GENERAL_NAME) *san_stack = (STACK_OF(GENERAL_NAME)*)X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL);
unsigned char *temp[sk_GENERAL_NAME_num(san_stack)];
GENERAL_NAME *name;
int i;
local_count = 0;
result = NULL;
name = NULL;
*count = 0;
if(san_stack == NULL)
return NULL;
while(sk_GENERAL_NAME_num(san_stack) > 0) {
name = sk_GENERAL_NAME_pop(san_stack);
switch(name->type) {
case GEN_DNS:
temp[local_count] = strndup(ASN1_STRING_data(name->d.dNSName), ASN1_STRING_length(name->d.dNSName)
+ 1);
if(temp[local_count] == NULL)
conf_err("out of memory");
local_count++;
break;
default:
logmsg(LOG_INFO, "unsupported subjectAltName type encountered: %i", name->type);
}
GENERAL_NAME_free(name);
}
result = (unsigned char**)malloc(sizeof(unsigned char*)*local_count);
if(result == NULL)
conf_err("out of memory");
for(i = 0;i < local_count; i++) {
result[i] = strndup(temp[i], strlen(temp[i])+1);
if(result[i] == NULL)
conf_err("out of memory");
free(temp[i]);
}
*count = local_count;
sk_GENERAL_NAME_pop_free(san_stack, GENERAL_NAME_free);
return result;
}
/*
* parse a back-end
*/
static BACKEND *
parse_be(const int is_emergency)
{
char lin[MAXBUF];
BACKEND *res;
int has_addr, has_port;
struct hostent *host;
struct sockaddr_in in;
struct sockaddr_in6 in6;
if((res = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
conf_err("BackEnd config: out of memory - aborted");
memset(res, 0, sizeof(BACKEND));
res->be_type = 0;
res->addr.ai_socktype = SOCK_STREAM;
res->to = is_emergency? 120: be_to;
res->conn_to = is_emergency? 120: be_connto;
res->alive = 1;
memset(&res->addr, 0, sizeof(res->addr));
res->priority = 5;
memset(&res->ha_addr, 0, sizeof(res->ha_addr));
res->url = NULL;
res->next = NULL;
has_addr = has_port = 0;
pthread_mutex_init(&res->mut, NULL);
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&Address, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC)) {
/* if we can't resolve it assume this is a UNIX domain socket */
res->addr.ai_socktype = SOCK_STREAM;
res->addr.ai_family = AF_UNIX;
res->addr.ai_protocol = 0;
if((res->addr.ai_addr = (struct sockaddr *)malloc(sizeof(struct sockaddr_un))) == NULL)
conf_err("out of memory");
if((strlen(lin + matches[1].rm_so) + 1) > UNIX_PATH_MAX)
conf_err("UNIX path name too long");
res->addr.ai_addrlen = strlen(lin + matches[1].rm_so) + 1;
res->addr.ai_addr->sa_family = AF_UNIX;
strcpy(res->addr.ai_addr->sa_data, lin + matches[1].rm_so);
res->addr.ai_addrlen = sizeof( struct sockaddr_un );
}
has_addr = 1;
} else if(!regexec(&Port, lin, 4, matches, 0)) {
switch(res->addr.ai_family) {
case AF_INET:
memcpy(&in, res->addr.ai_addr, sizeof(in));
in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in, sizeof(in));
break;
case AF_INET6:
memcpy(&in6, res->addr.ai_addr, sizeof(in6));
in6.sin6_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in6, sizeof(in6));
break;
default:
conf_err("Port is supported only for INET/INET6 back-ends");
}
has_port = 1;
} else if(!regexec(&Priority, lin, 4, matches, 0)) {
if(is_emergency)
conf_err("Priority is not supported for Emergency back-ends");
res->priority = atoi(lin + matches[1].rm_so);
} else if(!regexec(&TimeOut, lin, 4, matches, 0)) {
res->to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&ConnTO, lin, 4, matches, 0)) {
res->conn_to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&HAport, lin, 4, matches, 0)) {
if(is_emergency)
conf_err("HAport is not supported for Emergency back-ends");
res->ha_addr = res->addr;
if((res->ha_addr.ai_addr = (struct sockaddr *)malloc(res->addr.ai_addrlen)) == NULL)
conf_err("out of memory");
memcpy(res->ha_addr.ai_addr, res->addr.ai_addr, res->addr.ai_addrlen);
switch(res->addr.ai_family) {
case AF_INET:
memcpy(&in, res->ha_addr.ai_addr, sizeof(in));
in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->ha_addr.ai_addr, &in, sizeof(in));
break;
case AF_INET6:
memcpy(&in6, res->addr.ai_addr, sizeof(in6));
in6.sin6_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in6, sizeof(in6));
break;
default:
conf_err("HAport is supported only for INET/INET6 back-ends");
}
} else if(!regexec(&HAportAddr, lin, 4, matches, 0)) {
if(is_emergency)
conf_err("HAportAddr is not supported for Emergency back-ends");
lin[matches[1].rm_eo] = '\0';
if(get_host(lin + matches[1].rm_so, &res->ha_addr, PF_UNSPEC)) {
/* if we can't resolve it assume this is a UNIX domain socket */
res->addr.ai_socktype = SOCK_STREAM;
res->ha_addr.ai_family = AF_UNIX;
res->ha_addr.ai_protocol = 0;
if((res->ha_addr.ai_addr = (struct sockaddr *)strdup(lin + matches[1].rm_so)) == NULL)
conf_err("out of memory");
res->addr.ai_addrlen = strlen(lin + matches[1].rm_so) + 1;
} else switch(res->ha_addr.ai_family) {
case AF_INET:
memcpy(&in, res->ha_addr.ai_addr, sizeof(in));
in.sin_port = (in_port_t)htons(atoi(lin + matches[2].rm_so));
memcpy(res->ha_addr.ai_addr, &in, sizeof(in));
break;
case AF_INET6:
memcpy(&in6, res->ha_addr.ai_addr, sizeof(in6));
in6.sin6_port = (in_port_t)htons(atoi(lin + matches[2].rm_so));
memcpy(res->ha_addr.ai_addr, &in6, sizeof(in6));
break;
default:
conf_err("Unknown HA address type");
}
} else if(!regexec(&HTTPS, lin, 4, matches, 0)) {
if((res->ctx = SSL_CTX_new(SSLv23_client_method())) == NULL)
conf_err("SSL_CTX_new failed - aborted");
SSL_CTX_set_app_data(res->ctx, res);
SSL_CTX_set_verify(res->ctx, SSL_VERIFY_NONE, NULL);
SSL_CTX_set_mode(res->ctx, SSL_MODE_AUTO_RETRY);
#ifdef SSL_MODE_SEND_FALLBACK_SCSV
SSL_CTX_set_mode(res->ctx, SSL_MODE_SEND_FALLBACK_SCSV);
#endif
SSL_CTX_set_options(res->ctx, SSL_OP_ALL);
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(res->ctx, SSL_OP_NO_COMPRESSION);
#endif
SSL_CTX_clear_options(res->ctx, SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
SSL_CTX_clear_options(res->ctx, SSL_OP_LEGACY_SERVER_CONNECT);
sprintf(lin, "%d-Pound-%ld", getpid(), random());
SSL_CTX_set_session_id_context(res->ctx, (unsigned char *)lin, strlen(lin));
SSL_CTX_set_tmp_rsa_callback(res->ctx, RSA_tmp_callback);
SSL_CTX_set_tmp_dh_callback(res->ctx, DH_tmp_callback);
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
/* This generates a EC_KEY structure with no key, but a group defined */
EC_KEY *ecdh;
if((ecdh = EC_KEY_new_by_curve_name(EC_nid)) == NULL)
conf_err("Unable to generate temp ECDH key");
SSL_CTX_set_tmp_ecdh(res->ctx, ecdh);
SSL_CTX_set_options(res->ctx, SSL_OP_SINGLE_ECDH_USE);
EC_KEY_free(ecdh);
#endif
#endif
} else if(!regexec(&Cert, lin, 4, matches, 0)) {
if(res->ctx == NULL)
conf_err("BackEnd Cert can only be used after HTTPS - aborted");
lin[matches[1].rm_eo] = '\0';
if(SSL_CTX_use_certificate_chain_file(res->ctx, lin + matches[1].rm_so) != 1)
conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
if(SSL_CTX_use_PrivateKey_file(res->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
if(SSL_CTX_check_private_key(res->ctx) != 1)
conf_err("SSL_CTX_check_private_key failed - aborted");
} else if(!regexec(&Ciphers, lin, 4, matches, 0)) {
if(res->ctx == NULL)
conf_err("BackEnd Ciphers can only be used after HTTPS - aborted");
lin[matches[1].rm_eo] = '\0';
SSL_CTX_set_cipher_list(res->ctx, lin + matches[1].rm_so);
} else if(!regexec(&DisableProto, lin, 4, matches, 0)) {
if(res->ctx == NULL)
conf_err("BackEnd Disable can only be used after HTTPS - aborted");
lin[matches[1].rm_eo] = '\0';
if(strcasecmp(lin + matches[1].rm_so, "SSLv2") == 0)
SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2);
else if(strcasecmp(lin + matches[1].rm_so, "SSLv3") == 0)
SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
#ifdef SSL_OP_NO_TLSv1
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1") == 0)
SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1);
#endif
#ifdef SSL_OP_NO_TLSv1_1
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_1") == 0)
SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
#endif
#ifdef SSL_OP_NO_TLSv1_2
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_2") == 0)
SSL_CTX_set_options(res->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2);
#endif
} else if(!regexec(&Disabled, lin, 4, matches, 0)) {
res->disabled = atoi(lin + matches[1].rm_so);
} else if(!regexec(&End, lin, 4, matches, 0)) {
if(!has_addr)
conf_err("BackEnd missing Address - aborted");
if((res->addr.ai_family == AF_INET || res->addr.ai_family == AF_INET6) && !has_port)
conf_err("BackEnd missing Port - aborted");
return res;
} else {
conf_err("unknown directive");
}
}
conf_err("BackEnd premature EOF");
return NULL;
}
/*
* parse a session
*/
static void
parse_sess(SERVICE *const svc)
{
char lin[MAXBUF], *cp, *parm;
parm = NULL;
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&Type, lin, 4, matches, 0)) {
if(svc->sess_type != SESS_NONE)
conf_err("Multiple Session types in one Service - aborted");
lin[matches[1].rm_eo] = '\0';
cp = lin + matches[1].rm_so;
if(!strcasecmp(cp, "IP"))
svc->sess_type = SESS_IP;
else if(!strcasecmp(cp, "COOKIE"))
svc->sess_type = SESS_COOKIE;
else if(!strcasecmp(cp, "URL"))
svc->sess_type = SESS_URL;
else if(!strcasecmp(cp, "PARM"))
svc->sess_type = SESS_PARM;
else if(!strcasecmp(cp, "BASIC"))
svc->sess_type = SESS_BASIC;
else if(!strcasecmp(cp, "HEADER"))
svc->sess_type = SESS_HEADER;
else
conf_err("Unknown Session type");
} else if(!regexec(&TTL, lin, 4, matches, 0)) {
svc->sess_ttl = atoi(lin + matches[1].rm_so);
} else if(!regexec(&ID, lin, 4, matches, 0)) {
if(svc->sess_type != SESS_COOKIE && svc->sess_type != SESS_URL && svc->sess_type != SESS_HEADER)
conf_err("no ID permitted unless COOKIE/URL/HEADER Session - aborted");
lin[matches[1].rm_eo] = '\0';
if((parm = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("ID config: out of memory - aborted");
} else if(!regexec(&End, lin, 4, matches, 0)) {
if(svc->sess_type == SESS_NONE)
conf_err("Session type not defined - aborted");
if(svc->sess_ttl == 0)
conf_err("Session TTL not defined - aborted");
if((svc->sess_type == SESS_COOKIE || svc->sess_type == SESS_URL || svc->sess_type == SESS_HEADER)
&& parm == NULL)
conf_err("Session ID not defined - aborted");
if(svc->sess_type == SESS_COOKIE) {
snprintf(lin, MAXBUF - 1, "Cookie[^:]*:.*[ \t]%s=", parm);
if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("COOKIE pattern failed - aborted");
if(regcomp(&svc->sess_pat, "([^;]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("COOKIE pattern failed - aborted");
} else if(svc->sess_type == SESS_URL) {
snprintf(lin, MAXBUF - 1, "[?&]%s=", parm);
if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("URL pattern failed - aborted");
if(regcomp(&svc->sess_pat, "([^&;#]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("URL pattern failed - aborted");
} else if(svc->sess_type == SESS_PARM) {
if(regcomp(&svc->sess_start, ";", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("PARM pattern failed - aborted");
if(regcomp(&svc->sess_pat, "([^?]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("PARM pattern failed - aborted");
} else if(svc->sess_type == SESS_BASIC) {
if(regcomp(&svc->sess_start, "Authorization:[ \t]*Basic[ \t]*", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("BASIC pattern failed - aborted");
if(regcomp(&svc->sess_pat, "([^ \t]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("BASIC pattern failed - aborted");
} else if(svc->sess_type == SESS_HEADER) {
snprintf(lin, MAXBUF - 1, "%s:[ \t]*", parm);
if(regcomp(&svc->sess_start, lin, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HEADER pattern failed - aborted");
if(regcomp(&svc->sess_pat, "([^ \t]*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HEADER pattern failed - aborted");
}
if(parm != NULL)
free(parm);
return;
} else {
conf_err("unknown directive");
}
}
conf_err("Session premature EOF");
return;
}
/*
* basic hashing function, based on fmv
*/
static unsigned long
t_hash(const TABNODE *e)
{
unsigned long res;
char *k;
k = e->key;
res = 2166136261;
while(*k)
res = ((res ^ *k++) * 16777619) & 0xFFFFFFFF;
return res;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
static IMPLEMENT_LHASH_HASH_FN(t, TABNODE)
#else
static IMPLEMENT_LHASH_HASH_FN(t_hash, const TABNODE *)
#endif
static int
t_cmp(const TABNODE *d1, const TABNODE *d2)
{
return strcmp(d1->key, d2->key);
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
static IMPLEMENT_LHASH_COMP_FN(t, TABNODE)
#else
static IMPLEMENT_LHASH_COMP_FN(t_cmp, const TABNODE *)
#endif
/*
* parse a service
*/
static SERVICE *
parse_service(const char *svc_name)
{
char lin[MAXBUF];
SERVICE *res;
BACKEND *be;
MATCHER *m;
int ign_case;
if((res = (SERVICE *)malloc(sizeof(SERVICE))) == NULL)
conf_err("Service config: out of memory - aborted");
memset(res, 0, sizeof(SERVICE));
res->sess_type = SESS_NONE;
pthread_mutex_init(&res->mut, NULL);
if(svc_name)
strncpy(res->name, svc_name, KEY_SIZE);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((res->sessions = LHM_lh_new(TABNODE, t)) == NULL)
#else
if((res->sessions = lh_new(LHASH_HASH_FN(t_hash), LHASH_COMP_FN(t_cmp))) == NULL)
#endif
conf_err("lh_new failed - aborted");
ign_case = ignore_case;
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&URL, lin, 4, matches, 0)) {
if(res->url) {
for(m = res->url; m->next; m = m->next)
;
if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("URL config: out of memory - aborted");
m = m->next;
} else {
if((res->url = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("URL config: out of memory - aborted");
m = res->url;
}
memset(m, 0, sizeof(MATCHER));
lin[matches[1].rm_eo] = '\0';
if(regcomp(&m->pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ign_case? REG_ICASE: 0)))
conf_err("URL bad pattern - aborted");
} else if(!regexec(&HeadRequire, lin, 4, matches, 0)) {
if(res->req_head) {
for(m = res->req_head; m->next; m = m->next)
;
if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRequire config: out of memory - aborted");
m = m->next;
} else {
if((res->req_head = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRequire config: out of memory - aborted");
m = res->req_head;
}
memset(m, 0, sizeof(MATCHER));
lin[matches[1].rm_eo] = '\0';
if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HeadRequire bad pattern - aborted");
} else if(!regexec(&HeadDeny, lin, 4, matches, 0)) {
if(res->deny_head) {
for(m = res->deny_head; m->next; m = m->next)
;
if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadDeny config: out of memory - aborted");
m = m->next;
} else {
if((res->deny_head = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadDeny config: out of memory - aborted");
m = res->deny_head;
}
memset(m, 0, sizeof(MATCHER));
lin[matches[1].rm_eo] = '\0';
if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HeadDeny bad pattern - aborted");
} else if(!regexec(&Redirect, lin, 4, matches, 0)) {
if(res->backends) {
for(be = res->backends; be->next; be = be->next)
;
if((be->next = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
conf_err("Redirect config: out of memory - aborted");
be = be->next;
} else {
if((res->backends = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
conf_err("Redirect config: out of memory - aborted");
be = res->backends;
}
memset(be, 0, sizeof(BACKEND));
be->be_type = 302;
be->priority = 1;
be->alive = 1;
pthread_mutex_init(& be->mut, NULL);
lin[matches[1].rm_eo] = '\0';
if((be->url = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("Redirector config: out of memory - aborted");
/* split the URL into its fields */
if(regexec(&LOCATION, be->url, 4, matches, 0))
conf_err("Redirect bad URL - aborted");
if((be->redir_req = matches[3].rm_eo - matches[3].rm_so) == 1)
/* the path is a single '/', so remove it */
be->url[matches[3].rm_so] = '\0';
} else if(!regexec(&RedirectN, lin, 4, matches, 0)) {
if(res->backends) {
for(be = res->backends; be->next; be = be->next)
;
if((be->next = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
conf_err("Redirect config: out of memory - aborted");
be = be->next;
} else {
if((res->backends = (BACKEND *)malloc(sizeof(BACKEND))) == NULL)
conf_err("Redirect config: out of memory - aborted");
be = res->backends;
}
memset(be, 0, sizeof(BACKEND));
be->be_type = atoi(lin + matches[1].rm_so);
be->priority = 1;
be->alive = 1;
pthread_mutex_init(& be->mut, NULL);
lin[matches[2].rm_eo] = '\0';
if((be->url = strdup(lin + matches[2].rm_so)) == NULL)
conf_err("Redirector config: out of memory - aborted");
/* split the URL into its fields */
if(regexec(&LOCATION, be->url, 4, matches, 0))
conf_err("Redirect bad URL - aborted");
if((be->redir_req = matches[3].rm_eo - matches[3].rm_so) == 1)
/* the path is a single '/', so remove it */
be->url[matches[3].rm_so] = '\0';
} else if(!regexec(&BackEnd, lin, 4, matches, 0)) {
if(res->backends) {
for(be = res->backends; be->next; be = be->next)
;
be->next = parse_be(0);
} else
res->backends = parse_be(0);
} else if(!regexec(&Emergency, lin, 4, matches, 0)) {
res->emergency = parse_be(1);
} else if(!regexec(&Session, lin, 4, matches, 0)) {
parse_sess(res);
} else if(!regexec(&IgnoreCase, lin, 4, matches, 0)) {
ign_case = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Disabled, lin, 4, matches, 0)) {
res->disabled = atoi(lin + matches[1].rm_so);
} else if(!regexec(&End, lin, 4, matches, 0)) {
for(be = res->backends; be; be = be->next) {
if(!be->disabled)
res->tot_pri += be->priority;
res->abs_pri += be->priority;
}
return res;
} else {
conf_err("unknown directive");
}
}
conf_err("Service premature EOF");
return NULL;
}
/*
* return the file contents as a string
*/
static char *
file2str(const char *fname)
{
char *res;
struct stat st;
int fin;
if(stat(fname, &st))
conf_err("can't stat Err file - aborted");
if((fin = open(fname, O_RDONLY)) < 0)
conf_err("can't open Err file - aborted");
if((res = malloc(st.st_size + 1)) == NULL)
conf_err("can't alloc Err file (out of memory) - aborted");
if(read(fin, res, st.st_size) != st.st_size)
conf_err("can't read Err file - aborted");
res[st.st_size] = '\0';
close(fin);
return res;
}
/*
* parse an HTTP listener
*/
static LISTENER *
parse_HTTP(void)
{
char lin[MAXBUF];
LISTENER *res;
SERVICE *svc;
MATCHER *m;
int has_addr, has_port;
struct sockaddr_in in;
struct sockaddr_in6 in6;
if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL)
conf_err("ListenHTTP config: out of memory - aborted");
memset(res, 0, sizeof(LISTENER));
res->to = clnt_to;
res->rewr_loc = 1;
res->err414 = "Request URI is too long";
res->err500 = "An internal server error occurred. Please try again later.";
res->err501 = "This method may not be used.";
res->err503 = "The service is not available. Please try again later.";
res->log_level = log_level;
if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("xHTTP bad default pattern - aborted");
has_addr = has_port = 0;
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&Address, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC))
conf_err("Unknown Listener address");
if(res->addr.ai_family != AF_INET && res->addr.ai_family != AF_INET6)
conf_err("Unknown Listener address family");
has_addr = 1;
} else if(!regexec(&Port, lin, 4, matches, 0)) {
switch(res->addr.ai_family) {
case AF_INET:
memcpy(&in, res->addr.ai_addr, sizeof(in));
in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in, sizeof(in));
break;
case AF_INET6:
memcpy(&in6, res->addr.ai_addr, sizeof(in6));
in6.sin6_port = htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in6, sizeof(in6));
break;
default:
conf_err("Unknown Listener address family");
}
has_port = 1;
} else if(!regexec(&xHTTP, lin, 4, matches, 0)) {
int n;
n = atoi(lin + matches[1].rm_so);
regfree(&res->verb);
if(regcomp(&res->verb, xhttp[n], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("xHTTP bad pattern - aborted");
} else if(!regexec(&Client, lin, 4, matches, 0)) {
res->to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&CheckURL, lin, 4, matches, 0)) {
if(res->has_pat)
conf_err("CheckURL multiple pattern - aborted");
lin[matches[1].rm_eo] = '\0';
if(regcomp(&res->url_pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ignore_case? REG_ICASE: 0)))
conf_err("CheckURL bad pattern - aborted");
res->has_pat = 1;
} else if(!regexec(&Err414, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err414 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err500, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err500 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err501, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err501 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err503, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err503 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&MaxRequest, lin, 4, matches, 0)) {
res->max_req = ATOL(lin + matches[1].rm_so);
} else if(!regexec(&HeadRemove, lin, 4, matches, 0)) {
if(res->head_off) {
for(m = res->head_off; m->next; m = m->next)
;
if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRemove config: out of memory - aborted");
m = m->next;
} else {
if((res->head_off = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRemove config: out of memory - aborted");
m = res->head_off;
}
memset(m, 0, sizeof(MATCHER));
lin[matches[1].rm_eo] = '\0';
if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HeadRemove bad pattern - aborted");
} else if(!regexec(&AddHeader, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(res->add_head == NULL) {
if((res->add_head = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("AddHeader config: out of memory - aborted");
} else {
if((res->add_head = realloc(res->add_head, strlen(res->add_head) + strlen(lin + matches[1].rm_so) + 3))
== NULL)
conf_err("AddHeader config: out of memory - aborted");
strcat(res->add_head, "\r\n");
strcat(res->add_head, lin + matches[1].rm_so);
}
} else if(!regexec(&RewriteLocation, lin, 4, matches, 0)) {
res->rewr_loc = atoi(lin + matches[1].rm_so);
} else if(!regexec(&RewriteDestination, lin, 4, matches, 0)) {
res->rewr_dest = atoi(lin + matches[1].rm_so);
} else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
res->log_level = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Service, lin, 4, matches, 0)) {
if(res->services == NULL)
res->services = parse_service(NULL);
else {
for(svc = res->services; svc->next; svc = svc->next)
;
svc->next = parse_service(NULL);
}
} else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(res->services == NULL)
res->services = parse_service(lin + matches[1].rm_so);
else {
for(svc = res->services; svc->next; svc = svc->next)
;
svc->next = parse_service(lin + matches[1].rm_so);
}
} else if(!regexec(&End, lin, 4, matches, 0)) {
if(!has_addr || !has_port)
conf_err("ListenHTTP missing Address or Port - aborted");
return res;
} else {
conf_err("unknown directive - aborted");
}
}
conf_err("ListenHTTP premature EOF");
return NULL;
}
/*
* Dummy certificate verification - always OK
*/
static int
verify_OK(int pre_ok, X509_STORE_CTX *ctx)
{
return 1;
}
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
static int
SNI_server_name(SSL *ssl, int *dummy, POUND_CTX *ctx)
{
const char *server_name;
POUND_CTX *pc;
if((server_name = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) == NULL)
return SSL_TLSEXT_ERR_NOACK;
/* logmsg(LOG_DEBUG, "Received SSL SNI Header for servername %s", servername); */
SSL_set_SSL_CTX(ssl, NULL);
for(pc = ctx; pc; pc = pc->next) {
if(fnmatch(pc->server_name, server_name, 0) == 0) {
/* logmsg(LOG_DEBUG, "Found cert for %s", servername); */
SSL_set_SSL_CTX(ssl, pc->ctx);
return SSL_TLSEXT_ERR_OK;
}
else if(pc->subjectAltNameCount > 0 && pc->subjectAltNames != NULL) {
int i;
for(i = 0; i < pc->subjectAltNameCount; i++) {
if(fnmatch(pc->subjectAltNames[i], server_name, 0) == 0) {
SSL_set_SSL_CTX(ssl, pc->ctx);
return SSL_TLSEXT_ERR_OK;
}
}
}
}
/* logmsg(LOG_DEBUG, "No match for %s, default used", server_name); */
SSL_set_SSL_CTX(ssl, ctx->ctx);
return SSL_TLSEXT_ERR_OK;
}
#endif
/*
* parse an HTTPS listener
*/
static LISTENER *
parse_HTTPS(void)
{
char lin[MAXBUF];
LISTENER *res;
SERVICE *svc;
MATCHER *m;
int has_addr, has_port, has_other;
long ssl_op_enable, ssl_op_disable;
struct hostent *host;
struct sockaddr_in in;
struct sockaddr_in6 in6;
POUND_CTX *pc;
ssl_op_enable = SSL_OP_ALL;
#ifdef SSL_OP_NO_COMPRESSION
ssl_op_enable |= SSL_OP_NO_COMPRESSION;
#endif
ssl_op_disable = SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION | SSL_OP_LEGACY_SERVER_CONNECT
| SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS;
if((res = (LISTENER *)malloc(sizeof(LISTENER))) == NULL)
conf_err("ListenHTTPS config: out of memory - aborted");
memset(res, 0, sizeof(LISTENER));
res->to = clnt_to;
res->rewr_loc = 1;
res->err414 = "Request URI is too long";
res->err500 = "An internal server error occurred. Please try again later.";
res->err501 = "This method may not be used.";
res->err503 = "The service is not available. Please try again later.";
res->allow_client_reneg = 0;
res->log_level = log_level;
if(regcomp(&res->verb, xhttp[0], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("xHTTP bad default pattern - aborted");
has_addr = has_port = has_other = 0;
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&Address, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(get_host(lin + matches[1].rm_so, &res->addr, PF_UNSPEC))
conf_err("Unknown Listener address");
if(res->addr.ai_family != AF_INET && res->addr.ai_family != AF_INET6)
conf_err("Unknown Listener address family");
has_addr = 1;
} else if(!regexec(&Port, lin, 4, matches, 0)) {
if(res->addr.ai_family == AF_INET) {
memcpy(&in, res->addr.ai_addr, sizeof(in));
in.sin_port = (in_port_t)htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in, sizeof(in));
} else {
memcpy(&in6, res->addr.ai_addr, sizeof(in6));
in6.sin6_port = htons(atoi(lin + matches[1].rm_so));
memcpy(res->addr.ai_addr, &in6, sizeof(in6));
}
has_port = 1;
} else if(!regexec(&xHTTP, lin, 4, matches, 0)) {
int n;
n = atoi(lin + matches[1].rm_so);
regfree(&res->verb);
if(regcomp(&res->verb, xhttp[n], REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("xHTTP bad pattern - aborted");
} else if(!regexec(&Client, lin, 4, matches, 0)) {
res->to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&CheckURL, lin, 4, matches, 0)) {
if(res->has_pat)
conf_err("CheckURL multiple pattern - aborted");
lin[matches[1].rm_eo] = '\0';
if(regcomp(&res->url_pat, lin + matches[1].rm_so, REG_NEWLINE | REG_EXTENDED | (ignore_case? REG_ICASE: 0)))
conf_err("CheckURL bad pattern - aborted");
res->has_pat = 1;
} else if(!regexec(&Err414, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err414 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err500, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err500 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err501, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err501 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&Err503, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
res->err503 = file2str(lin + matches[1].rm_so);
} else if(!regexec(&MaxRequest, lin, 4, matches, 0)) {
res->max_req = ATOL(lin + matches[1].rm_so);
} else if(!regexec(&HeadRemove, lin, 4, matches, 0)) {
if(res->head_off) {
for(m = res->head_off; m->next; m = m->next)
;
if((m->next = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRemove config: out of memory - aborted");
m = m->next;
} else {
if((res->head_off = (MATCHER *)malloc(sizeof(MATCHER))) == NULL)
conf_err("HeadRemove config: out of memory - aborted");
m = res->head_off;
}
memset(m, 0, sizeof(MATCHER));
lin[matches[1].rm_eo] = '\0';
if(regcomp(&m->pat, lin + matches[1].rm_so, REG_ICASE | REG_NEWLINE | REG_EXTENDED))
conf_err("HeadRemove bad pattern - aborted");
} else if(!regexec(&RewriteLocation, lin, 4, matches, 0)) {
res->rewr_loc = atoi(lin + matches[1].rm_so);
} else if(!regexec(&RewriteDestination, lin, 4, matches, 0)) {
res->rewr_dest = atoi(lin + matches[1].rm_so);
} else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
res->log_level = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Cert, lin, 4, matches, 0)) {
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
/* we have support for SNI */
FILE *fcert;
char server_name[MAXBUF], *cp;
X509 *x509;
if(has_other)
conf_err("Cert directives MUST precede other SSL-specific directives - aborted");
if(res->ctx) {
for(pc = res->ctx; pc->next; pc = pc->next)
;
if((pc->next = malloc(sizeof(POUND_CTX))) == NULL)
conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
pc = pc->next;
} else {
if((res->ctx = malloc(sizeof(POUND_CTX))) == NULL)
conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
pc = res->ctx;
}
if((pc->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
conf_err("SSL_CTX_new failed - aborted");
pc->server_name = NULL;
pc->next = NULL;
lin[matches[1].rm_eo] = '\0';
if(SSL_CTX_use_certificate_chain_file(pc->ctx, lin + matches[1].rm_so) != 1)
conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
if(SSL_CTX_use_PrivateKey_file(pc->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
if(SSL_CTX_check_private_key(pc->ctx) != 1)
conf_err("SSL_CTX_check_private_key failed - aborted");
if((fcert = fopen(lin + matches[1].rm_so, "r")) == NULL)
conf_err("ListenHTTPS: could not open certificate file");
if((x509 = PEM_read_X509(fcert, NULL, NULL, NULL)) == NULL)
conf_err("ListenHTTPS: could not get certificate subject");
fclose(fcert);
memset(server_name, '\0', MAXBUF);
X509_NAME_oneline(X509_get_subject_name(x509), server_name, MAXBUF - 1);
pc->subjectAltNameCount = 0;
pc->subjectAltNames = NULL;
pc->subjectAltNames = get_subjectaltnames(x509, &(pc->subjectAltNameCount));
X509_free(x509);
if(!regexec(&CNName, server_name, 4, matches, 0)) {
server_name[matches[1].rm_eo] = '\0';
if((pc->server_name = strdup(server_name + matches[1].rm_so)) == NULL)
conf_err("ListenHTTPS: could not set certificate subject");
} else
conf_err("ListenHTTPS: could not get certificate CN");
#else
/* no SNI support */
if(has_other)
conf_err("Cert directives MUST precede other SSL-specific directives - aborted");
if(res->ctx)
conf_err("ListenHTTPS: multiple certificates not supported - aborted");
if((res->ctx = malloc(sizeof(POUND_CTX))) == NULL)
conf_err("ListenHTTPS new POUND_CTX: out of memory - aborted");
res->ctx->server_name = NULL;
res->ctx->next = NULL;
if((res->ctx->ctx = SSL_CTX_new(SSLv23_server_method())) == NULL)
conf_err("SSL_CTX_new failed - aborted");
lin[matches[1].rm_eo] = '\0';
if(SSL_CTX_use_certificate_chain_file(res->ctx->ctx, lin + matches[1].rm_so) != 1)
conf_err("SSL_CTX_use_certificate_chain_file failed - aborted");
if(SSL_CTX_use_PrivateKey_file(res->ctx->ctx, lin + matches[1].rm_so, SSL_FILETYPE_PEM) != 1)
conf_err("SSL_CTX_use_PrivateKey_file failed - aborted");
if(SSL_CTX_check_private_key(res->ctx->ctx) != 1)
conf_err("SSL_CTX_check_private_key failed - aborted");
#endif
} else if(!regexec(&ClientCert, lin, 4, matches, 0)) {
has_other = 1;
if(res->ctx == NULL)
conf_err("ClientCert may only be used after Cert - aborted");
switch(res->clnt_check = atoi(lin + matches[1].rm_so)) {
case 0:
/* don't ask */
for(pc = res->ctx; pc; pc = pc->next)
SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_NONE, NULL);
break;
case 1:
/* ask but OK if no client certificate */
for(pc = res->ctx; pc; pc = pc->next) {
SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL);
SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
}
break;
case 2:
/* ask and fail if no client certificate */
for(pc = res->ctx; pc; pc = pc->next) {
SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
}
break;
case 3:
/* ask but do not verify client certificate */
for(pc = res->ctx; pc; pc = pc->next) {
SSL_CTX_set_verify(pc->ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, verify_OK);
SSL_CTX_set_verify_depth(pc->ctx, atoi(lin + matches[2].rm_so));
}
break;
}
} else if(!regexec(&AddHeader, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(res->add_head == NULL) {
if((res->add_head = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("AddHeader config: out of memory - aborted");
} else {
if((res->add_head = realloc(res->add_head, strlen(res->add_head) + strlen(lin + matches[1].rm_so) + 3)) == NULL)
conf_err("AddHeader config: out of memory - aborted");
strcat(res->add_head, "\r\n");
strcat(res->add_head, lin + matches[1].rm_so);
}
} else if(!regexec(&DisableProto, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(strcasecmp(lin + matches[1].rm_so, "SSLv2") == 0)
ssl_op_enable |= SSL_OP_NO_SSLv2;
else if(strcasecmp(lin + matches[1].rm_so, "SSLv3") == 0)
ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
#ifdef SSL_OP_NO_TLSv1
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1") == 0)
ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1;
#endif
#ifdef SSL_OP_NO_TLSv1_1
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_1") == 0)
ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1;
#endif
#ifdef SSL_OP_NO_TLSv1_2
else if(strcasecmp(lin + matches[1].rm_so, "TLSv1_2") == 0)
ssl_op_enable |= SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1_2;
#endif
} else if(!regexec(&SSLAllowClientRenegotiation, lin, 4, matches, 0)) {
res->allow_client_reneg = atoi(lin + matches[1].rm_so);
if (res->allow_client_reneg == 2) {
ssl_op_enable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
ssl_op_disable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
} else {
ssl_op_disable |= SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
ssl_op_enable &= ~SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION;
}
} else if(!regexec(&SSLHonorCipherOrder, lin, 4, matches, 0)) {
if (atoi(lin + matches[1].rm_so)) {
ssl_op_enable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
ssl_op_disable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
} else {
ssl_op_disable |= SSL_OP_CIPHER_SERVER_PREFERENCE;
ssl_op_enable &= ~SSL_OP_CIPHER_SERVER_PREFERENCE;
}
} else if(!regexec(&Ciphers, lin, 4, matches, 0)) {
has_other = 1;
if(res->ctx == NULL)
conf_err("Ciphers may only be used after Cert - aborted");
lin[matches[1].rm_eo] = '\0';
for(pc = res->ctx; pc; pc = pc->next)
SSL_CTX_set_cipher_list(pc->ctx, lin + matches[1].rm_so);
} else if(!regexec(&CAlist, lin, 4, matches, 0)) {
STACK_OF(X509_NAME) *cert_names;
has_other = 1;
if(res->ctx == NULL)
conf_err("CAList may only be used after Cert - aborted");
lin[matches[1].rm_eo] = '\0';
if((cert_names = SSL_load_client_CA_file(lin + matches[1].rm_so)) == NULL)
conf_err("SSL_load_client_CA_file failed - aborted");
for(pc = res->ctx; pc; pc = pc->next)
SSL_CTX_set_client_CA_list(pc->ctx, cert_names);
} else if(!regexec(&VerifyList, lin, 4, matches, 0)) {
has_other = 1;
if(res->ctx == NULL)
conf_err("VerifyList may only be used after Cert - aborted");
lin[matches[1].rm_eo] = '\0';
for(pc = res->ctx; pc; pc = pc->next)
if(SSL_CTX_load_verify_locations(pc->ctx, lin + matches[1].rm_so, NULL) != 1)
conf_err("SSL_CTX_load_verify_locations failed - aborted");
} else if(!regexec(&CRLlist, lin, 4, matches, 0)) {
#if HAVE_X509_STORE_SET_FLAGS
X509_STORE *store;
X509_LOOKUP *lookup;
has_other = 1;
if(res->ctx == NULL)
conf_err("CRLlist may only be used after Cert - aborted");
lin[matches[1].rm_eo] = '\0';
for(pc = res->ctx; pc; pc = pc->next) {
store = SSL_CTX_get_cert_store(pc->ctx);
if((lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file())) == NULL)
conf_err("X509_STORE_add_lookup failed - aborted");
if(X509_load_crl_file(lookup, lin + matches[1].rm_so, X509_FILETYPE_PEM) != 1)
conf_err("X509_load_crl_file failed - aborted");
X509_STORE_set_flags(store, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL);
}
#else
conf_err("your version of OpenSSL does not support CRL checking");
#endif
} else if(!regexec(&NoHTTPS11, lin, 4, matches, 0)) {
res->noHTTPS11 = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Service, lin, 4, matches, 0)) {
if(res->services == NULL)
res->services = parse_service(NULL);
else {
for(svc = res->services; svc->next; svc = svc->next)
;
svc->next = parse_service(NULL);
}
} else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(res->services == NULL)
res->services = parse_service(lin + matches[1].rm_so);
else {
for(svc = res->services; svc->next; svc = svc->next)
;
svc->next = parse_service(lin + matches[1].rm_so);
}
} else if(!regexec(&End, lin, 4, matches, 0)) {
X509_STORE *store;
if(!has_addr || !has_port || res->ctx == NULL)
conf_err("ListenHTTPS missing Address, Port or Certificate - aborted");
#ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB
if(res->ctx->next)
if(!SSL_CTX_set_tlsext_servername_callback(res->ctx->ctx, SNI_server_name)
|| !SSL_CTX_set_tlsext_servername_arg(res->ctx->ctx, res->ctx))
conf_err("ListenHTTPS: can't set SNI callback");
#endif
for(pc = res->ctx; pc; pc = pc->next) {
SSL_CTX_set_app_data(pc->ctx, res);
SSL_CTX_set_mode(pc->ctx, SSL_MODE_AUTO_RETRY);
SSL_CTX_set_options(pc->ctx, ssl_op_enable);
SSL_CTX_clear_options(pc->ctx, ssl_op_disable);
sprintf(lin, "%d-Pound-%ld", getpid(), random());
SSL_CTX_set_session_id_context(pc->ctx, (unsigned char *)lin, strlen(lin));
SSL_CTX_set_tmp_rsa_callback(pc->ctx, RSA_tmp_callback);
SSL_CTX_set_tmp_dh_callback(pc->ctx, DH_tmp_callback);
SSL_CTX_set_info_callback(pc->ctx, SSLINFO_callback);
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
/* This generates a EC_KEY structure with no key, but a group defined */
EC_KEY *ecdh;
if((ecdh = EC_KEY_new_by_curve_name(EC_nid)) == NULL)
conf_err("Unable to generate temp ECDH key");
SSL_CTX_set_tmp_ecdh(pc->ctx, ecdh);
SSL_CTX_set_options(pc->ctx, SSL_OP_SINGLE_ECDH_USE);
EC_KEY_free(ecdh);
#endif
#endif
}
return res;
} else {
conf_err("unknown directive");
}
}
conf_err("ListenHTTPS premature EOF");
return NULL;
}
/*
* parse the config file
*/
static void
parse_file(void)
{
char lin[MAXBUF];
SERVICE *svc;
LISTENER *lstn;
int i;
#if HAVE_OPENSSL_ENGINE_H
ENGINE *e;
#endif
while(conf_fgets(lin, MAXBUF)) {
if(strlen(lin) > 0 && lin[strlen(lin) - 1] == '\n')
lin[strlen(lin) - 1] = '\0';
if(!regexec(&User, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if((user = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("User config: out of memory - aborted");
} else if(!regexec(&Group, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if((group = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("Group config: out of memory - aborted");
} else if(!regexec(&RootJail, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if((root_jail = strdup(lin + matches[1].rm_so)) == NULL)
conf_err("RootJail config: out of memory - aborted");
} else if(!regexec(&Daemon, lin, 4, matches, 0)) {
daemonize = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Threads, lin, 4, matches, 0)) {
numthreads = atoi(lin + matches[1].rm_so);
} else if(!regexec(&LogFacility, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(lin[matches[1].rm_so] == '-')
def_facility = -1;
else
for(i = 0; facilitynames[i].c_name; i++)
if(!strcmp(facilitynames[i].c_name, lin + matches[1].rm_so)) {
def_facility = facilitynames[i].c_val;
break;
}
} else if(!regexec(&Grace, lin, 4, matches, 0)) {
grace = atoi(lin + matches[1].rm_so);
} else if(!regexec(&LogLevel, lin, 4, matches, 0)) {
log_level = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Client, lin, 4, matches, 0)) {
clnt_to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&Alive, lin, 4, matches, 0)) {
alive_to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&TimeOut, lin, 4, matches, 0)) {
be_to = atoi(lin + matches[1].rm_so);
} else if(!regexec(&ConnTO, lin, 4, matches, 0)) {
be_connto = atoi(lin + matches[1].rm_so);
} else if(!regexec(&IgnoreCase, lin, 4, matches, 0)) {
ignore_case = atoi(lin + matches[1].rm_so);
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
} else if(!regexec(&ECDHCurve, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if((EC_nid = OBJ_sn2nid(lin + matches[1].rm_so)) == 0)
conf_err("ECDHCurve config: invalid curve name");
#endif
#endif
#if HAVE_OPENSSL_ENGINE_H
} else if(!regexec(&SSLEngine, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
ENGINE_load_builtin_engines();
#endif
if (!(e = ENGINE_by_id(lin + matches[1].rm_so)))
conf_err("could not find engine");
if(!ENGINE_init(e)) {
ENGINE_free(e);
conf_err("could not init engine");
}
if(!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
ENGINE_free(e);
conf_err("could not set all defaults");
}
ENGINE_finish(e);
ENGINE_free(e);
#endif
} else if(!regexec(&Control, lin, 4, matches, 0)) {
if(ctrl_name != NULL)
conf_err("Control multiply defined - aborted");
lin[matches[1].rm_eo] = '\0';
ctrl_name = strdup(lin + matches[1].rm_so);
} else if(!regexec(&ListenHTTP, lin, 4, matches, 0)) {
if(listeners == NULL)
listeners = parse_HTTP();
else {
for(lstn = listeners; lstn->next; lstn = lstn->next)
;
lstn->next = parse_HTTP();
}
} else if(!regexec(&ListenHTTPS, lin, 4, matches, 0)) {
if(listeners == NULL)
listeners = parse_HTTPS();
else {
for(lstn = listeners; lstn->next; lstn = lstn->next)
;
lstn->next = parse_HTTPS();
}
} else if(!regexec(&Service, lin, 4, matches, 0)) {
if(services == NULL)
services = parse_service(NULL);
else {
for(svc = services; svc->next; svc = svc->next)
;
svc->next = parse_service(NULL);
}
} else if(!regexec(&ServiceName, lin, 4, matches, 0)) {
lin[matches[1].rm_eo] = '\0';
if(services == NULL)
services = parse_service(lin + matches[1].rm_so);
else {
for(svc = services; svc->next; svc = svc->next)
;
svc->next = parse_service(lin + matches[1].rm_so);
}
} else if(!regexec(&Anonymise, lin, 4, matches, 0)) {
anonymise = 1;
} else {
conf_err("unknown directive - aborted");
}
}
return;
}
/*
* prepare to parse the arguments/config file
*/
void
config_parse(const int argc, char **const argv)
{
char *conf_name;
FILE *f_conf;
int c_opt, check_only;
if(regcomp(&Empty, "^[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Comment, "^[ \t]*#.*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&User, "^[ \t]*User[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Group, "^[ \t]*Group[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RootJail, "^[ \t]*RootJail[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Daemon, "^[ \t]*Daemon[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Threads, "^[ \t]*Threads[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&LogFacility, "^[ \t]*LogFacility[ \t]+([a-z0-9-]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&LogLevel, "^[ \t]*LogLevel[ \t]+([0-5])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Grace, "^[ \t]*Grace[ \t]+([0-9]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Alive, "^[ \t]*Alive[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&SSLEngine, "^[ \t]*SSLEngine[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Control, "^[ \t]*Control[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ListenHTTP, "^[ \t]*ListenHTTP[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ListenHTTPS, "^[ \t]*ListenHTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&End, "^[ \t]*End[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Address, "^[ \t]*Address[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Port, "^[ \t]*Port[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Cert, "^[ \t]*Cert[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&xHTTP, "^[ \t]*xHTTP[ \t]+([01234])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Client, "^[ \t]*Client[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CheckURL, "^[ \t]*CheckURL[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Err414, "^[ \t]*Err414[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Err500, "^[ \t]*Err500[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Err501, "^[ \t]*Err501[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Err503, "^[ \t]*Err503[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&MaxRequest, "^[ \t]*MaxRequest[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HeadRemove, "^[ \t]*HeadRemove[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RewriteLocation, "^[ \t]*RewriteLocation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RewriteDestination, "^[ \t]*RewriteDestination[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Service, "^[ \t]*Service[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ServiceName, "^[ \t]*Service[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&URL, "^[ \t]*URL[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HeadRequire, "^[ \t]*HeadRequire[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HeadDeny, "^[ \t]*HeadDeny[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&BackEnd, "^[ \t]*BackEnd[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Emergency, "^[ \t]*Emergency[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Priority, "^[ \t]*Priority[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&TimeOut, "^[ \t]*TimeOut[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HAport, "^[ \t]*HAport[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HAportAddr, "^[ \t]*HAport[ \t]+([^ \t]+)[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Redirect, "^[ \t]*Redirect[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RedirectN, "^[ \t]*Redirect[ \t]+(30[127])[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Session, "^[ \t]*Session[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Type, "^[ \t]*Type[ \t]+([^ \t]+)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&TTL, "^[ \t]*TTL[ \t]+([1-9-][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ID, "^[ \t]*ID[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ClientCert, "^[ \t]*ClientCert[ \t]+([0-3])[ \t]+([1-9])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&AddHeader, "^[ \t]*AddHeader[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&SSLAllowClientRenegotiation, "^[ \t]*SSLAllowClientRenegotiation[ \t]+([012])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&DisableProto, "^[ \t]*Disable[ \t]+(SSLv2|SSLv3|TLSv1|TLSv1_1|TLSv1_2)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&SSLHonorCipherOrder, "^[ \t]*SSLHonorCipherOrder[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Ciphers, "^[ \t]*Ciphers[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CAlist, "^[ \t]*CAlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&VerifyList, "^[ \t]*VerifyList[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CRLlist, "^[ \t]*CRLlist[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&NoHTTPS11, "^[ \t]*NoHTTPS11[ \t]+([0-2])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Include, "^[ \t]*Include[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&ConnTO, "^[ \t]*ConnTO[ \t]+([1-9][0-9]*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&IgnoreCase, "^[ \t]*IgnoreCase[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&HTTPS, "^[ \t]*HTTPS[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Disabled, "^[ \t]*Disabled[ \t]+([01])[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CNName, ".*[Cc][Nn]=([-*.A-Za-z0-9]+).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&Anonymise, "^[ \t]*Anonymise[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
|| regcomp(&ECDHCurve, "^[ \t]*ECDHCurve[ \t]+\"(.+)\"[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
#endif
#endif
) {
logmsg(LOG_ERR, "bad config Regex - aborted");
exit(1);
}
opterr = 0;
check_only = 0;
conf_name = F_CONF;
pid_name = F_PID;
while((c_opt = getopt(argc, argv, "f:cvVp:")) > 0)
switch(c_opt) {
case 'f':
conf_name = optarg;
break;
case 'p':
pid_name = optarg;
break;
case 'c':
check_only = 1;
break;
case 'v':
print_log = 1;
break;
case 'V':
print_log = 1;
logmsg(LOG_DEBUG, "Version %s", VERSION);
logmsg(LOG_DEBUG, " Configuration switches:");
#ifdef C_SUPER
if(strcmp(C_SUPER, "0"))
logmsg(LOG_DEBUG, " --disable-super");
#endif
#ifdef C_SSL
if(strcmp(C_SSL, ""))
logmsg(LOG_DEBUG, " --with-ssl=%s", C_SSL);
#endif
#ifdef C_T_RSA
if(strcmp(C_T_RSA, "0"))
logmsg(LOG_DEBUG, " --with-t_rsa=%s", C_T_RSA);
#endif
#ifdef C_MAXBUF
if(strcmp(C_MAXBUF, "0"))
logmsg(LOG_DEBUG, " --with-maxbuf=%s", C_MAXBUF);
#endif
#ifdef C_OWNER
if(strcmp(C_OWNER, ""))
logmsg(LOG_DEBUG, " --with-owner=%s", C_OWNER);
#endif
#ifdef C_GROUP
if(strcmp(C_GROUP, ""))
logmsg(LOG_DEBUG, " --with-group=%s", C_GROUP);
#endif
#ifdef C_DH_LEN
if(strcmp(C_DH_LEN, "0"))
logmsg(LOG_DEBUG, " --with-dh=%s", C_DH_LEN);
#endif
logmsg(LOG_DEBUG, "Exiting...");
exit(0);
break;
default:
logmsg(LOG_ERR, "bad flag -%c", optopt);
exit(1);
break;
}
if(optind < argc) {
logmsg(LOG_ERR, "unknown extra arguments (%s...)", argv[optind]);
exit(1);
}
conf_init(conf_name);
user = NULL;
group = NULL;
root_jail = NULL;
ctrl_name = NULL;
numthreads = 128;
alive_to = 30;
daemonize = 1;
grace = 30;
services = NULL;
listeners = NULL;
parse_file();
if(check_only) {
logmsg(LOG_INFO, "Config file %s is OK", conf_name);
exit(0);
}
if(listeners == NULL) {
logmsg(LOG_ERR, "no listeners defined - aborted");
exit(1);
}
regfree(&Empty);
regfree(&Comment);
regfree(&User);
regfree(&Group);
regfree(&RootJail);
regfree(&Daemon);
regfree(&Threads);
regfree(&LogFacility);
regfree(&LogLevel);
regfree(&Grace);
regfree(&Alive);
regfree(&SSLEngine);
regfree(&Control);
regfree(&ListenHTTP);
regfree(&ListenHTTPS);
regfree(&End);
regfree(&Address);
regfree(&Port);
regfree(&Cert);
regfree(&xHTTP);
regfree(&Client);
regfree(&CheckURL);
regfree(&Err414);
regfree(&Err500);
regfree(&Err501);
regfree(&Err503);
regfree(&MaxRequest);
regfree(&HeadRemove);
regfree(&RewriteLocation);
regfree(&RewriteDestination);
regfree(&Service);
regfree(&ServiceName);
regfree(&URL);
regfree(&HeadRequire);
regfree(&HeadDeny);
regfree(&BackEnd);
regfree(&Emergency);
regfree(&Priority);
regfree(&TimeOut);
regfree(&HAport);
regfree(&HAportAddr);
regfree(&Redirect);
regfree(&RedirectN);
regfree(&Session);
regfree(&Type);
regfree(&TTL);
regfree(&ID);
regfree(&ClientCert);
regfree(&AddHeader);
regfree(&SSLAllowClientRenegotiation);
regfree(&DisableProto);
regfree(&SSLHonorCipherOrder);
regfree(&Ciphers);
regfree(&CAlist);
regfree(&VerifyList);
regfree(&CRLlist);
regfree(&NoHTTPS11);
regfree(&Include);
regfree(&ConnTO);
regfree(&IgnoreCase);
regfree(&HTTPS);
regfree(&Disabled);
regfree(&CNName);
regfree(&Anonymise);
#if OPENSSL_VERSION_NUMBER >= 0x0090800fL
#ifndef OPENSSL_NO_ECDH
regfree(&ECDHCurve);
#endif
#endif
/* set the facility only here to ensure the syslog gets opened if necessary */
log_facility = def_facility;
return;
}
Pound-2.8/README 0000755 0001750 0001750 00000105416 13275266545 012401 0 ustar roseg roseg POUND - REVERSE-PROXY AND LOAD-BALANCER
The Pound program is a reverse proxy, load balancer and
HTTPS front-end for Web server(s). Pound was developed
to enable distributing the load among several Web-servers
and to allow for a convenient SSL wrapper for those Web
servers that do not offer it natively. Pound is distributed
under the GPL - no warranty, it's free to use, copy and
give away.
WHAT POUND IS:
1. a reverse-proxy: it passes requests from client
browsers to one or more back-end servers.
2. a load balancer: it will distribute the requests from
the client browsers among several back-end servers,
while keeping session information.
3. an SSL wrapper: Pound will decrypt HTTPS requests
from client browsers and pass them as plain HTTP
to the back-end servers.
4. an HTTP/HTTPS sanitizer: Pound will verify requests
for correctness and accept only well-formed ones.
5. a fail over-server: should a back-end server fail,
Pound will take note of the fact and stop passing
requests to it until it recovers.
6. a request redirector: requests may be distributed
among servers according to the requested URL.
Pound is a very small program, easily audited for security
problems. It can run as setuid/setgid and/or in a chroot
jail. Pound does not access the hard-disk at all (except
for reading certificate file(s) on start, if required)
and should thus pose no security threat to any machine.
WHAT POUND IS NOT:
1. Pound is not a Web server: by itself, Pound serves no
content - it contacts the back-end server(s) for that
purpose.
2. Pound is not a Web accelerator: no caching is done -
every request is passed "as is" to a back-end server.
STATUS
As of release 1.0 Pound is declared to be production-quality code.
Quite a few people have reported using Pound successfully in production
environments. The largest volume reported to date is a site with an
average of about 30M requests per day, peaking at over 600 requests/sec.
Pound was successfully used in production with a variety of Web servers,
including Apache, IIS, Zope, WebLogic, Jakarta/Tomcat, iPlanet, etc. In
general Pound passes requests and responses back and forth unchanged,
so we have no reason to think that any web server would be incompatible.
Client browsers that were tested:
- IE 5.0/5.5 (Windows) HTTP/HTTPS
- Netscape 4.7 (Windows/Linux) HTTP/HTTPS
- Mozilla (Windows/Linux) HTTP/HTTPS
- Konqueror (Linux) HTTP/HTTPS
- Galleon (Linux) HTTP/HTTPS
- Opera (Linux/Windows) HTTP/HTTPS
- Lynx (Linux) HTTP
Given that Pound is in production and no problems were reported, we have
no reason to believe that other browsers would present a problem. A few
issues were observed with problematic SSL implementations, most notably
with Opera 6, but these should be OK in the present version.
INSTALLATION
Probably the easiest way to install Pound is to use a pre-compiled package
if you can find one. While Apsis offers no such packages, they are available
for quite a few systems (Suse, Debian and derivatives such as Ubuntu), as
well as some private packages:
- RPMs for RedHat are available at http://www.invoca.ch/pub/packages/pound/
- A nice FreeBSD live-CD distribution is available at http://www.targeted.org as
http://www.targeted.org/files/fbsd62_pound23.iso.gz, including a Pound binary.
Failing that you should install from sources:
1. Pound was tested on Linux, Solaris and OpenBSD, but
it should work unchanged on just about any modern
Unix-like system. You will require at least OpenSSL and
libpthread. The PCRE package is strongly recommended.
Warning: as Pound is a multi-threaded program it requires
a version of OpenSSL with thread support. This is normally
the case on Linux and Solaris (for example) but not on *BSD.
If your system has the wrong library please download, compile
and install OpenSSL (from http://www.openssl.org).
If the PCRE package is available Pound will link against it.
This will provide a significant performance boost.
2. Download the current version of Pound-current file and unpack
it. The archive is signed.
My signature is available at http://www.apsis.ch/pound/roseg.asc.
Alternately see below for stable versions.
Unpack. Do the usual thing:
./configure
3. The following options are available for the configure script:
--with-ssl=ssl_dir -- OpenSSL home directory (default: system defined).
--disable-super -- disable supervisor process (default: enabled)
--with-t_rsa=nnn -- timeout of the RSA ephemeral keys regeneration
(default: 1800 seconds).
--with-owner=owner -- name of installed binaries owner (default is
system-dependent).
--with-group=group -- name of installed binaries group (default is
system-dependent).
4. Check that the resulting Makefile is correct and possibly
adjust flags as needed on your system. Compile:
make
5. If it works, you may want to do some testing before installing.
6. Install the executable somewhere (it's likely that
/usr/local/sbin would make a good choice), as well
as the manual page (pound.8 -> /usr/local/man/man8).
The supplied Makefile will do it for you.
7. Make sure Pound gets started on boot. Read the man
page for available options and examples.
COPYRIGHT
Pound is copyrighted by Apsis GmbH and is distributed under
the terms of the GNU Public License with the additional
exemption that compiling, linking, and/or using OpenSSL is
allowed. Basically, this means that you can use it free of
charge, copy it, distribute it (provided the copyright is
maintained and the full package is distributed), modify it,
or line a bird-cage with it.
We would be happy to hear from you if you use it and
suggestions and improvements are gladly accepted.
CONTACT
Robert Segall, roseg@apsis.ch
Apsis GmbH, http://www.apsis.ch
P O Box
CH-8707 Uetikon am See
Switzerland
+41-44-920 4904
MAILING LIST
Pound has its own mailing list now: please send a message with
the subject "subscribe" to pound@apsis.ch in order to
subscribe. You will receive confirmation and instructions in
the reply.
All messages are available and indexed (searcheable) in the
archive http://www.apsis.ch/pound/pound_list.
The mailing list is the primary support forum for Pound - please
post there any questions you may have. The developpers' address is
given here for information purposes only.
ZOPE
A special note for Zope users: the original intent on
developing Pound was to allow distributing the load
among several Zope servers running on top of ZEO. This
it does.
A special problem arises when you try using Pound as an
SSL wrapper: Zope assumes that the requests are made via
HTTP and insists on prepending 'http://' to the (correct)
address in the replies, including in the tag and
the absolute URLs it generates (for images for example).
This is clearly an undesirable behavior.
For older Zope versions (prior to 2.7): a modified z2.py (as
well as a patch) is included in the distribution. The main
difference is that this z2.py allows starting an additional
HTTP server via the -y flag that sets the environment
HTTPS variable - thus correcting the problem. That means
that in order to use Pound as an SSL wrapper you need to:
- start Zope (modify the 'start' file) as:
python -X -w 8080 -y 8443 ...
For Zope 2.7 or later the same effect can be achieved via suitable
modifications to zope.conf.
VIRTUAL HOSTS (IN GENERAL)
Some people asked about the possibility of redirecting requests to back-ends
as per some virtual hosts definition. While I believe this is not Pound's
job, it can be done. As of version 0.10, Pound supports filtering requests
based not only on the request URL, but also on the presence or absence of
certain headers.
Let's assume that you have internal server 192.168.0.10 that is supposed to
serve the needs of virtual host www.server0.com and 192.168.0.11 that serves
www.server1.com. You want Pound to listen on address 1.2.3.4 and separate
the requests to each host. The config file would look something like this:
ListenHTTP
Address 1.2.3.4
Port 80
Service
HeadRequire "Host: .*www.server0.com.*"
BackEnd
Address 192.168.0.10
Port 80
End
End
Service
HeadRequire "Host: .*www.server1.com.*"
BackEnd
Address 192.168.0.11
Port 80
End
End
End
(add whatever else is necessary) or, if you want even safer filtering:
ListenHTTP
Address 1.2.3.4
Port 80
Service
HeadRequire "Host: .*www.server0.com.*"
HeadDeny "Host: .*www.server1.com.*"
BackEnd
Address 192.168.0.10
Port 80
End
End
Service
HeadRequire "Host: .*www.server1.com.*"
HeadDeny "Host: .*www.server0.com.*"
BackEnd
Address 192.168.0.11
Port 80
End
End
End
This is NOT recommended (I personally believe that virtual hosts should be
implemented in the back-end servers - putting this in a proxy
is a major security kludge) but it works.
VIRTUAL HOSTS AND HTTPS
Quite often we get inquiries about Pound's ability to do virtual hosting
with HTTPS. In order to lay this matter to rest, let me say:
HTTPS does not allow virtual hosting!
This is not a limitation of Pound, but of HTTPS - no Web server or proxy
are able to do it due to the nature of the beast.
In order to see why this is the case we need to look at the way HTTPS works.
Basically there are three stages in any HTTPS connection:
1. Connection negotiation - the client (your browser) and the server (Web
server or proxy) negotiate the basic parameters: ciphers to use, session
key, etc.
2. Connection authentication: at the very least the server presents the
client with a certificate that says "I am server www.encrypted.com - and
certificate.authority.org will verify that". The client may also present
a certificate of its own at this stage.
3. Request/response cycle: normal HTTP is sent (through the encrypted
channel) back and forth.
The vital point to notice here is that connection authentication takes place
BEFORE any request was issued.
On the other hand, the way virtual hosting works is for the client to
specify in the request to which server it would like to talk. This is
accomplished via a Host header:
GET /index.html HTTP/1.1
Host: http://www.virthost.com
Combining the two we get to an impasse: on connection setup the server will
reply with the certificate for "www.realhost.com", but the request is really
for "www.virthost.com" - and most browsers will scream blue murder (as well
they should) if the two do not match.
There is a new twist on this however: some of the newer browsers will accept
so-called "wild-card certificates". This is a specially crafted certificate
that is not issued to a host, but rather to a domain. The result is that
on setting-up a new SSL connection, the server replies not with "I am
www.encrypted.com", but with "I am *.encrypted.com". If the browser is
capable of processing this type of certificate then the connection is
set up and normal HTTPS (with www.encrypted.com or special.encrypted.com or
even some.other.server.encrypted.com or whatever other name matches) proceeds
as usual. Pound supports these certificates and you can use virtual hosts in
the normal way.
Update June 2010: starting with the 2.6 series, Pound has SNI support, if your
OpenSSL version supports it. Basically you supply Pound with several certificates,
one for each virtual host (wild card certificates - as described above - are
allowed). On connecting the client signals to which server it wants to talk,
and Pound searches among its certificates which would fit. Not all versions
of OpenSSL and not all clients support this mode, but if available it allows
for virtual hosts over HTTPS.
An additional option is to use a semi-official TLS extension, the so called
alternate subject name. If your version of OpenSSL supports it you may specify
in one certificate several alternate server names. This requires support for a
special TLS feature, and nor all clients accept it.
VIRTUAL HOSTS IN ZOPE
For reasons I can't quite grasp, it seems that a lot of Zope
users are convinced that virtual hosts are only possible through
the Apache/VHM combination and that it requires some kind of
magic incantation at midnight in order to work (I won't even
start on the virgin sacrifices).
The simple fact is that VHM and the Apache VirtualHost directives
(as well as various tricks through mod_rewrite and mod_proxy) are
(almost) mutually exclusive: they perform exactly the same
functions and, leaving aside the logging issues, are used
independently of each other. Let me repeat that: you may use the
VHM without Apache - just click on the VHM mappings tab and add
whatever virtual host you wish. From this moment on any request
to that host will be mapped back and forth by Zope to the required
URL. This works weather you access Zope directly or via any number
of proxies on the way, Pound included.
To test: add a new host name to your /etc/hosts file, making it an
alias for localhost - something like::
127.0.0.1 localhost www.testhost.mine
Add a mapping in VHM from www.testhost.mine to some Zope folder
(Examples is already there). Point your browser to http://localhost
and you get the normal Zope start page; point it to
http://www.testhost.mine and you'll see the Examples starting page.
All requests are mapped correctly, and the URLs in the pages (such
as base or absoluteURL) are translated correctly in the response.
SESSIONS
Pound has the ability to keep track of sessions between a client
browser and a back-end server. Unfortunately, HTTP is defined as
a stateless protocol, which complicates matters: many schemes have
been invented to allow keeping track of sessions, none of which works
perfectly. Even worse, sessions are critical in order to allow
web-based applications to function correctly - it is vital that once
a session is established all subsequent requests from the same browser
be directed to the same back-end server.
Six possible ways of detecting a session have been implemented in
Pound (hopefully the most useful ones): by client address, by Basic
authentication (user id/password), by URL parameter, by cookie, by
HTTP parameter and by header value.
- by client address: in this scheme Pound directs all requests from
the same client IP address to the same back-end server. Put the
lines
Session
Type IP
TTL 300
End
in the configuration file to achieve this effect. The value indicates
what period of inactivity is allowed before the session is discarded.
- by Basic Authentication: in this scheme Pound directs all requests from
the same user (as identified in the Basic Authentication header) to the
same back-end server. Put the lines
Session
Type Basic
TTL 300
End
in configuration file to achieve this effect. The value indicates what
period of inactivity is allowed before the session is discarded.
WARNING: given the constraints of the HTTP protocol it may very well be
that the authenticated request will go to a different back-end server than
the one originally requesting it. Make sure all your servers support
the same authentication scheme!
- by URL parameter: quite often session information is passed through URL
parameters (the browser is pointed to something like http://xxx?id=123).
Put the lines
Session
Type URL
ID "id"
TTL 300
End
to support this scheme and the sessions will be tracked based on the value
of the "id" parameter.
- by cookie value: applications that use this method pass a certain cookie
back and forth. Add the lines
Session
Type Cookie
ID "sess"
TTL 300
End
to your configuration file - the sessions will be tracked by the value of
the "sess" cookie.
- by HTTP parameter value: applications that use this method pass an HTTP
parameter (http://x.y/z;parameter) back and forth. Add the lines
Session
Type PARM
TTL 300
End
to your configuration file - the sessions will be tracked by the value of
the parameter.
- by header value: applications that use this method pass a certain header
back and forth. Add the lines
Session
Type Header
ID "X-sess"
TTL 300
End
to your configuration file - the sessions will be tracked by the value of
the "X-sess" header.
Please note the following restrictions on session tracking:
- session tracking is always associated with a certain Service. Thus each
group may have other methods and parameters.
- there is no default session: if you have not defined any sessions no
session tracking will be done.
- only one session definition is allowed per Service. If your application
has alternative methods for sessions you will have to define a separate
Service for each method.
A note on cookie injection: some applications have no session-tracking mechanism at
all but would still like to have the client always directed to the same back-end
time after time. Some reverse proxies use a mechanism called "cookie injection" in
order to achieve this: a cookie is added to the back-end responses and tracked by the
reverse proxy.
Pound was designed to be as transparent as possible, and this mechanism is not
supported. If you really need this sort of persistent mapping use the client address
session mechanism (Session Type IP), which achieves the same result without
changing the contents in any way.
REQUEST LOGGING
As a general rule, Pound passes all headers as they arrive from the client
browser to the back-end server(s). There are two exceptions to this rule:
Pound may add information about the SSL client certificate (as described
below), and it will add an X-Forwarded-For header. The general format is:
X-Forwarded-for: client-IP-address
The back-end server(s) may use this extra information in order to create
their log-files with the real client address (otherwise all requests will
appear to originate from Pound itself, which is rather useless).
In addition, Pound logs requests and replies to the system log. This is
controlled by the LogLevel configuration variable (0 - no logging,
1 - normal log, 2 - full log, 3 - Apache combined log format, 4 - Apache
combined log format without virtual host).
By default the messages go to the LOG_DAEMON facility, but you can change
this in the configuration file. If you don't want to, you can just do a:
fgrep pound /var/log/messages
to get all the messages generated by Pound.
HTTPS CERTIFICATES
If a client browser connects via HTTPS and if it presents a
certificate and if HTTPSHeaders is set, Pound will obtain the
certificate data and add the following HTTP headers to the
request it makes to the server:
- X-SSL-Subject: information about the certificate owner
- X-SSL-Issuer: information about the certificate issuer (CA)
- X-SSL-notBefore: begin validity date for the certificate
- X-SSL-notAfter: end validity date for the certificate
- X-SSL-serial: certificate serial number (in decimal)
- X-SSL-cipher: the cipher currently in use
- X-SSL-certificate: the full client certificate (multi-line)
It is the application's responsibility to actually use these
headers - Pound just passes this information without checking
it in any way (except for signature and encryption correctness).
Please note that this mechanism allows forgeries: a client may
(maliciously) send these headers to Pound in order to masquerade
as an SSL client with a specific certificate. If this is a problem
for your application make sure to deny these requests. Add:
HeadDeny "X-SSL-Subject:.*"
HeadDeny "X-SSL-Issuer:.*"
HeadDeny "X-SSL-notBefore:.*"
HeadDeny "X-SSL-notAfter:.*"
HeadDeny "X-SSL-serial:.*"
HeadDeny "X-SSL-cipher:.*"
within the Service(s).
THREADS AND LIMITS
A few people ran into problems when installing Pound because of the
various threading models and how they interact with system-imposed
limits. Please keep in mind the following requirements:
- on most System V derived Unices (of which Linux up to 2.4 is one),
a thread is a process. This means that when doing a 'ps' you will see
as many processes with the name 'pound' as there are active threads.
Each such process uses only two file descriptors, but the system needs
to support the required number of processes, both in total and per
user (possibly also per process group). In bash, this is 'ulimit -u',
in csh this is 'limit maxproc'.
- on BSD style systems all threads run in the same process space. Do
a ps and you see a single 'pound' process. The process needs two
file descriptors per active request (bash: 'ulimit -n', csh
'limit maxfiles'/'limit openfiles').
- on most systems the thread library comes with a built-in limit on the
maximal number of concurrent threads allowed - on older systems it usually
is 1024, on newer systems quite a bit higher. In very
rare cases (very high load and long response times) you may run into
this limitation - the symptom is log messages saying "can't create
thread". Your only solution is to recompile the system threads library
(and possibly the kernel itself) with a higher limit.
Please note that your kernel needs to be configured to support the
required resources - the above are just the shell commands.
SIMILAR SYSTEMS
Quite a few people asked "What is wrong with Apache/Squid/
stunnel/your_favorite? Do we really need another proxy
system?". The simple answer is that there is nothing wrong -
they are all excellent systems that do their jobs very well.
The reasoning behind Pound is however slightly different:
- In my experience, a load-balancer may easily become a
bottle-neck in itself. If you have a heavily loaded site,
there are few things more depressing than seeing your
"load-balancer" slow down the entire network. This means that
the load-balancer should be kept as light-weight as possible.
- Security: auditing a large system for security issues is a
major undertaking for anybody (ask Bill Gates about it). This
implies that in order to avoid introducing new vulnerabilities
into a system (after all, your installation is only as secure
as its weakest component) the proxy/load-balancer should be
kept as small as possible.
- Protection: I assume Pound will be the only component exposed
to the Internet - your back-end servers will run in a protected
network behind it. This means that Pound should filter requests
and make sure only valid, correctly formed ones are passed to the
back-end servers, thus protecting them from malicious clients.
Taking these criteria into consideration, it is easy to see why
the other systems mentioned above do not fit:
- Apache (with mod_proxy and mod_backhand): great system, but very
large. Imposes a significant load on the system, complex set-up
procedure (and it is so easy to get it wrong: check how many Apache
servers allow proxying from and to external hosts). While Apache
has proven remarkably exploit free, I wouldn't wish to go into a
security audit for the tens of thousands of lines of code involved,
not to mention all the additional modules.
- Squid: great caching proxy, but even should load-balancing
features become available in the future, do you really need
caching on the load-balancer? After all, Pound can easily run on a
disk-less system, whereas with Squid you'd better prepare a high
throughput RAID. Squid is still perfectly usable as a caching
proxy between Pound and the actual Web server, should it lack
its own cache (which Zope happily has).
- stunnel: probably comes closest to my understanding of software
design (does one job only and does it very well). However, it
lacks the load balancing and HTTP filtering features that I
considered necessary. Using stunnel in front of Pound (for HTTPS)
would have made sense, except that integrating HTTPS into Pound
proved to be so simple that it was not worth the trouble.
- your favourite system: let me know how it looks in light of the
above criteria - I am always interested in new ideas.
DEDICATED SERVERS
Some people asked about the possibility of dedicating specific
back-end servers to some clients - in other words, if a request
originates from a certain IP address or group of addresses then
it should be sent to a specific group of back-end servers.
Given the ease with which IP addresses can be forged I am personally
doubtful of the utility of such a feature. Even should you think it
desirable, it is probably best implemented via the packet filter,
rather than a proxy server. Assuming that requests from x.com are
to go to s1.local, requests from y.com to s2.local and everything
else to s3.local and s4.local, here is how to do it:
- make sure your firewall blocks requests to port 8080, 8081 and 8082
- configure Pound as follows:
ListenHTTP
Address 127.0.0.1
Port 8080
Service
BackEnd
Address s1.local
Port 80
End
End
End
ListenHTTP
Address 127.0.0.1
Port 8081
Service
BackEnd
Address s2.local
Port 80
End
End
End
ListenHTTP
Address 127.0.0.1
Port 8082
Service
BackEnd
Address s3.local
Port 80
End
BackEnd
Address s4.local
Port 80
End
End
End
- have your packet filter redirect requests to the right local ports
based on the origin address. In OpenBSD pf syntax this would be
something like:
rdr on rl0 from x.com to myhost.com port 80 -> localhost port 8080
rdr on rl0 from y.com to myhost.com port 80 -> localhost port 8081
rdr on rl0 from any to myhost.com port 80 -> localhost port 8082
or in Linux iptables::
iptables -t nat -A PREROUTING -p tcp -s x.com --dport 80 -i eth0 \
-j DNAT --to 127.0.0.1:8080
iptables -t nat -A PREROUTING -p tcp -s y.com --dport 80 -i eth0 \
-j DNAT --to 127.0.0.1:8081
iptables -t nat -A PREROUTING -p tcp --dport 80 -i eth0 -j DNAT \
--to 127.0.0.1:8082
This would give you the desired effect and probably better
performance than a purely proxy-based solution (though the
performance improvement is debatable, at least on Linux).
WebDAV
As of version 1.0 Pound supports the full WebDAV command-set. In
fact, it has been tested and is known to (almost) work with the
Microsoft Outlook Web Gateway, which is quite remarkable given that
Microsoft's own proxy does not.
Regrettably, Microsoft adherence to standards leaves something to be
desired: they decided to add some characters to their URLs - thus
breaking a whole set of RFC's.
Rather then change Pound to accept these characters (which could create
some serious issues with security on other systems) we have made this
behaviour dependent on a configuration switch: xHTTP (see the man page
for details).
If you also use the SSL wrapper feature in front of a Microsoft server
you should probably also add 'AddHeader "Front-End-Https: on"'.
These changes are also required to access a Subversion server via
Pound.
OTHER ISSUES
The following problems were reported by various people who use pound:
- delays in loading pages when the client browser is IE 5.5 (possibly
limited to W2K/XP). It seems that IE opens exactly 4 connections (sockets)
to the server and keeps them open until some time-out or until the server
closes the connection. This works fine, unless you redirect IE to another
server - given that all 4 sockets are used IE waits for a while before
the redirect is actually performed.
Solution: use the directive "Client 1" to ensure that Pound closes
sockets very early, thus freeing the necessary resources. Experiment with
the time-out - as it may cause problems with slow connections.
- Pound fails to start; HTTPS is enabled and the message "can't read
private key from file xxx" appears in the log.
Solution: make sure that the certificate file includes:
- (optional) a chain of certificates from a known certificate authority to
your server certificate
- the server certificate
- the private key; the key may NOT be password-protected
The file should be in PEM format. The OpenSSL command to generate a
self-signed certificate in the correct format would be something like::
openssl req -x509 -newkey rsa:1024 -keyout test.pem -out test.pem \
-days 365 -nodes
Note the '-nodes' flag - it's important!
- Pound fails to operate correctly with SSL when RootJail is specified.
Solution: OpenSSL requires access to /dev/urandom, so make sure such a
device is accessible from the root jail directory. Thus if your root
jail is something like /var/pound:
mkdir /var/pound/dev
mknod /var/pound/dev/urandom c 1 9
or whatever major/minor number are appropriate for your system.
- In chroot mode logging may stop functioning.
Solution: make sure /dev and the root jail are on the same filesystem
and create a hard link in the root jail to /dev/log:
mkdir /chroot/jail/dev
ln /dev/log /chroot/jail/dev/log
Alternately you can have syslog (or syslog-ng) listen on another
socket - see the man page for details.
- In chroot mode name resolution (and especially redirects) may stop
functioning. Solution: make sure your resolver works correctly in the
jail. You probably need copies of /etc/resolv.conf and (at least part)
of /etc/hosts. Depending on your system additional files may be required
check your resolver man page for details. Should name resolution fail the
translation of host names to IP addresses would fail, thereby defeating
the mechanism Pound uses to identify when should a Redirect be rewritten.
- IE 5.x fails to work (correctly or at all) with Pound in HTTPS mode.
Solution: define the supported OpenSSL ciphers for IE compatibility (this
is really a work-around for a known IE bug):
Ciphers "ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL"
(Thanks to Andi Roedl for the tip).
- Linux-specific: some people use various redundant Pound solutions for
Linux which require Pound instances on separate machines to bind to the
same address. The default configuration of Linux does not allow a
program to bind() to non-local addresses, which may cause a problem.
Solution: add
echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
in your start-up script, or just set
net.ipv4.ip_nonlocal_bind = 1
in /etc/sysctl.conf (if you have one).
(Thanks to RUne Saetre for the suggestion).
ACKNOWLEDGMENTS
Albert (of Alacra) for investigating and writing the TCP_NODELAY code.
Luuk de Boer did some serious testing and debugging of the WebDAV
code for Microsoft servers.
Alession Cervellin packages and makes available Solaris packages for
various Pound versions.
David Couture found some nasty, lurking bugs, as well as contributing
some serious testing on big hardware.
Frank Denis contributed a few excellent code patches and some good ideas.
Dmitriy Dvoinikov makes available a live-CD FreeBSD distribution that
includes a Pound binary.
Abner G. Jacobsen did a lot of testing in a production environment
and contributed some very nice ideas.
Akira Higuchi found a significant security issue in Pound and contributed
the code to fix it.
Ken Lalonde contributed very useful remarks and suggestions, as well as
correcting a few code errors.
Phil Lodwick contributed essential parts of the high-availability code and
came up with some good ideas. In addition, did some serious testing under
heavy loads.
Simon Matter packages and makes available RPMs for various Pound versions.
Jan-Piet Mens raised some interesting security points about the HTTPS
implementation and brought the original idea for SSL header filtering.
Andreas Roedl for testing and some ideas about logging in root jails.
Gurkan Sengun tested Pound on Solaris, contributed the Solaris cc flags
and makes a Solaris pre-compiled version available on his Web-site
(www.linuks.mine.nu)
Shinji Tanaka contributed a patch for controlling logging to disk files.
This is available at http://www.hatena-inc.co.jp/~stanaka/pound/
Jim Washington contributed the code for WebDAV and tested it.
Maxime Yve discovered a nasty bug in the session tracking code and
contributed the patch to fix it.
All the others who tested Pound and told me about their results.
Pound-2.8/install-sh 0000755 0001750 0001750 00000012736 13275266545 013524 0 ustar roseg roseg #!/bin/sh
#
# install - install a program, script, or datafile
# This comes from X11R5 (mit/util/scripts/install.sh).
#
# Copyright 1991 by the Massachusetts Institute of Technology
#
# Permission to use, copy, modify, distribute, and sell this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of M.I.T. not be used in advertising or
# publicity pertaining to distribution of the software without specific,
# written prior permission. M.I.T. makes no representations about the
# suitability of this software for any purpose. It is provided "as is"
# without express or implied warranty.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd="$cpprog"
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd="$stripprog"
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "install: no input file specified"
exit 1
else
true
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d $dst ]; then
instcmd=:
chmodcmd=""
else
instcmd=mkdir
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f $src -o -d $src ]
then
true
else
echo "install: $src does not exist"
exit 1
fi
if [ x"$dst" = x ]
then
echo "install: no destination specified"
exit 1
else
true
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d $dst ]
then
dst="$dst"/`basename $src`
else
true
fi
fi
## this sed command emulates the dirname command
dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-${defaultIFS}}"
oIFS="${IFS}"
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS="${oIFS}"
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp="${pathcomp}${1}"
shift
if [ ! -d "${pathcomp}" ] ;
then
$mkdirprog "${pathcomp}"
else
true
fi
pathcomp="${pathcomp}/"
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd $dst &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename $dst`
else
dstfile=`basename $dst $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename $dst`
else
true
fi
# Make a temp file name in the proper directory.
dsttmp=$dstdir/#inst.$$#
# Move or copy the file name to the temp name
$doit $instcmd $src $dsttmp &&
trap "rm -f ${dsttmp}" 0 &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
# Now rename the file to the real destination.
$doit $rmcmd -f $dstdir/$dstfile &&
$doit $mvcmd $dsttmp $dstdir/$dstfile
fi &&
exit 0
Pound-2.8/GPL.txt 0000755 0001750 0001750 00000104513 13275266545 012701 0 ustar roseg roseg GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
Copyright (C)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
Copyright (C)
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
Pound-2.8/svc.c 0000644 0001750 0001750 00000146460 13275266545 012461 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#include "pound.h"
#ifndef LHASH_OF
#define LHASH_OF(x) LHASH
#define CHECKED_LHASH_OF(type, h) h
#endif
/*
* Add a new key/content pair to a hash table
* the table should be already locked
*/
static void
t_add(LHASH_OF(TABNODE) *const tab, const char *key, const void *content, const size_t cont_len)
{
TABNODE *t, *old;
if((t = (TABNODE *)malloc(sizeof(TABNODE))) == NULL) {
logmsg(LOG_WARNING, "t_add() content malloc");
return;
}
if((t->key = strdup(key)) == NULL) {
free(t);
logmsg(LOG_WARNING, "t_add() strdup");
return;
}
if((t->content = malloc(cont_len)) == NULL) {
free(t->key);
free(t);
logmsg(LOG_WARNING, "t_add() content malloc");
return;
}
memcpy(t->content, content, cont_len);
t->last_acc = time(NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((old = LHM_lh_insert(TABNODE, tab, t)) != NULL) {
#else
if((old = (TABNODE *)lh_insert(tab, t)) != NULL) {
#endif
free(old->key);
free(old->content);
free(old);
logmsg(LOG_WARNING, "t_add() DUP");
}
return;
}
/*
* Find a key
* returns the content in the parameter
* side-effect: update the time of last access
*/
static void *
t_find(LHASH_OF(TABNODE) *const tab, char *const key)
{
TABNODE t, *res;
t.key = key;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((res = (TABNODE *)LHM_lh_retrieve(TABNODE, tab, &t)) != NULL) {
#else
if((res = (TABNODE *)lh_retrieve(tab, &t)) != NULL) {
#endif
res->last_acc = time(NULL);
return res->content;
}
return NULL;
}
/*
* Delete a key
*/
static void
t_remove(LHASH_OF(TABNODE) *const tab, char *const key)
{
TABNODE t, *res;
t.key = key;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((res = LHM_lh_delete(TABNODE, tab, &t)) != NULL) {
#else
if((res = (TABNODE *)lh_delete(tab, &t)) != NULL) {
#endif
free(res->key);
free(res->content);
free(res);
}
return;
}
typedef struct {
LHASH_OF(TABNODE) *tab;
time_t lim;
void *content;
int cont_len;
} ALL_ARG;
static void
t_old_doall_arg(TABNODE *t, ALL_ARG *a)
{
TABNODE *res;
if(t->last_acc < a->lim)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((res = LHM_lh_delete(TABNODE, a->tab, t)) != NULL) {
#else
if((res = lh_delete(a->tab, t)) != NULL) {
#endif
free(res->key);
free(res->content);
free(res);
}
return;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
IMPLEMENT_LHASH_DOALL_ARG_FN(t_old, TABNODE, ALL_ARG)
#else
#define t_old t_old_doall_arg
IMPLEMENT_LHASH_DOALL_ARG_FN(t_old, TABNODE *, ALL_ARG *)
#endif
/*
* Expire all old nodes
*/
static void
t_expire(LHASH_OF(TABNODE) *const tab, const time_t lim)
{
ALL_ARG a;
int down_load;
a.tab = tab;
a.lim = lim;
down_load = CHECKED_LHASH_OF(TABNODE, tab)->down_load;
CHECKED_LHASH_OF(TABNODE, tab)->down_load = 0;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
LHM_lh_doall_arg(TABNODE, tab, LHASH_DOALL_ARG_FN(t_old), ALL_ARG, &a);
#else
lh_doall_arg(tab, LHASH_DOALL_ARG_FN(t_old), &a);
#endif
CHECKED_LHASH_OF(TABNODE, tab)->down_load = down_load;
return;
}
static void
t_cont_doall_arg(TABNODE *t, ALL_ARG *arg)
{
TABNODE *res;
if(memcmp(t->content, arg->content, arg->cont_len) == 0)
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
if((res = LHM_lh_delete(TABNODE, arg->tab, t)) != NULL) {
#else
if((res = lh_delete(arg->tab, t)) != NULL) {
#endif
free(res->key);
free(res->content);
free(res);
}
return;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
IMPLEMENT_LHASH_DOALL_ARG_FN(t_cont, TABNODE, ALL_ARG)
#else
#define t_cont t_cont_doall_arg
IMPLEMENT_LHASH_DOALL_ARG_FN(t_cont, TABNODE *, ALL_ARG *)
#endif
/*
* Remove all nodes with the given content
*/
static void
t_clean(LHASH_OF(TABNODE) *const tab, void *const content, const size_t cont_len)
{
ALL_ARG a;
int down_load;
a.tab = tab;
a.content = content;
a.cont_len = cont_len;
down_load = CHECKED_LHASH_OF(TABNODE, tab)->down_load;
CHECKED_LHASH_OF(TABNODE, tab)->down_load = 0;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
LHM_lh_doall_arg(TABNODE, tab, LHASH_DOALL_ARG_FN(t_cont), ALL_ARG, &a);
#else
lh_doall_arg(tab, LHASH_DOALL_ARG_FN(t_cont), &a);
#endif
CHECKED_LHASH_OF(TABNODE, tab)->down_load = down_load;
return;
}
/*
* Log an error to the syslog or to stderr
*/
#ifdef HAVE_STDARG_H
void
logmsg(const int priority, const char *fmt, ...)
{
char buf[MAXBUF + 1];
va_list ap;
struct tm *t_now, t_res;
buf[MAXBUF] = '\0';
va_start(ap, fmt);
vsnprintf(buf, MAXBUF, fmt, ap);
va_end(ap);
if(log_facility == -1) {
fprintf((priority == LOG_INFO || priority == LOG_DEBUG)? stdout: stderr, "%s\n", buf);
} else {
if(print_log)
printf("%s\n", buf);
else
syslog(log_facility | priority, "%s", buf);
}
return;
}
#else
void
logmsg(const int priority, const char *fmt, va_alist)
va_dcl
{
char buf[MAXBUF + 1];
va_list ap;
struct tm *t_now, t_res;
buf[MAXBUF] = '\0';
va_start(ap);
vsnprintf(buf, MAXBUF, fmt, ap);
va_end(ap);
if(log_facility == -1) {
fprintf((priority == LOG_INFO || priority == LOG_DEBUG)? stdout: stderr, "%s\n", buf);
} else {
if(print_log)
printf("%s\n", buf);
else
syslog(log_facility | priority, "%s", buf);
}
return;
}
#endif
/*
* Translate inet/inet6 address/port into a string
*/
void
addr2str(char *const res, const int res_len, const struct addrinfo *addr, const int no_port)
{
char buf[MAXBUF];
int port;
void *src;
memset(res, 0, res_len);
#ifdef HAVE_INET_NTOP
switch(addr->ai_family) {
case AF_INET:
src = (void *)&((struct sockaddr_in *)addr->ai_addr)->sin_addr.s_addr;
port = ntohs(((struct sockaddr_in *)addr->ai_addr)->sin_port);
if(inet_ntop(AF_INET, src, buf, MAXBUF - 1) == NULL)
strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
break;
case AF_INET6:
src = (void *)&((struct sockaddr_in6 *)addr->ai_addr)->sin6_addr.s6_addr;
port = ntohs(((struct sockaddr_in6 *)addr->ai_addr)->sin6_port);
if(inet_ntop(AF_INET6, src, buf, MAXBUF - 1) == NULL)
strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
break;
case AF_UNIX:
strncpy(buf, (char *)addr->ai_addr, MAXBUF - 1);
port = 0;
break;
default:
strncpy(buf, "(UNKNOWN)", MAXBUF - 1);
port = 0;
break;
}
if(no_port)
snprintf(res, res_len, "%s", buf);
else
snprintf(res, res_len, "%s:%d", buf, port);
#else
#error "Pound needs inet_ntop()"
#endif
return;
}
/*
* Parse a URL, possibly decoding hexadecimal-encoded characters
*/
int
cpURL(char *res, char *src, int len)
{
int state;
char *kp_res;
for(kp_res = res, state = 0; len > 0; len--)
switch(state) {
case 1:
if(*src >= '0' && *src <= '9') {
*res = *src++ - '0';
state = 2;
} else if(*src >= 'A' && *src <= 'F') {
*res = *src++ - 'A' + 10;
state = 2;
} else if(*src >= 'a' && *src <= 'f') {
*res = *src++ - 'a' + 10;
state = 2;
} else {
*res++ = '%';
*res++ = *src++;
state = 0;
}
break;
case 2:
if(*src >= '0' && *src <= '9') {
*res = *res * 16 + *src++ - '0';
res++;
state = 0;
} else if(*src >= 'A' && *src <= 'F') {
*res = *res * 16 + *src++ - 'A' + 10;
res++;
state = 0;
} else if(*src >= 'a' && *src <= 'f') {
*res = *res * 16 + *src++ - 'a' + 10;
res++;
state = 0;
} else {
*res++ = '%';
*res++ = *(src - 1);
*res++ = *src++;
state = 0;
}
break;
default:
if(*src != '%')
*res++ = *src++;
else {
src++;
state = 1;
}
break;
}
if(state > 0)
*res++ = '%';
if(state > 1)
*res++ = *(src - 1);
*res = '\0';
return res - kp_res;
}
/*
* Parse a header
* return a code and possibly content in the arg
*/
int
check_header(const char *header, char *const content)
{
regmatch_t matches[4];
static struct {
char header[32];
int len;
int val;
} hd_types[] = {
{ "Transfer-encoding", 17, HEADER_TRANSFER_ENCODING },
{ "Content-length", 14, HEADER_CONTENT_LENGTH },
{ "Connection", 10, HEADER_CONNECTION },
{ "Location", 8, HEADER_LOCATION },
{ "Content-location", 16, HEADER_CONTLOCATION },
{ "Host", 4, HEADER_HOST },
{ "Referer", 7, HEADER_REFERER },
{ "User-agent", 10, HEADER_USER_AGENT },
{ "Destination", 11, HEADER_DESTINATION },
{ "Expect", 6, HEADER_EXPECT },
{ "", 0, HEADER_OTHER },
};
int i;
if(!regexec(&HEADER, header, 4, matches, 0)) {
for(i = 0; hd_types[i].len > 0; i++)
if((matches[1].rm_eo - matches[1].rm_so) == hd_types[i].len
&& strncasecmp(header + matches[1].rm_so, hd_types[i].header, hd_types[i].len) == 0) {
/* we know that the original header was read into a buffer of size MAXBUF, so no overflow */
strncpy(content, header + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
content[matches[2].rm_eo - matches[2].rm_so] = '\0';
return hd_types[i].val;
}
return HEADER_OTHER;
} else
return HEADER_ILLEGAL;
}
static int
match_service(const SERVICE *svc, const char *request, char **const headers)
{
MATCHER *m;
int i, found;
/* check for request */
for(m = svc->url; m; m = m->next)
if(regexec(&m->pat, request, 0, NULL, 0))
return 0;
/* check for required headers */
for(m = svc->req_head; m; m = m->next) {
for(found = i = 0; i < (MAXHEADERS - 1) && !found; i++)
if(headers[i] && !regexec(&m->pat, headers[i], 0, NULL, 0))
found = 1;
if(!found)
return 0;
}
/* check for forbidden headers */
for(m = svc->deny_head; m; m = m->next) {
for(found = i = 0; i < (MAXHEADERS - 1) && !found; i++)
if(headers[i] && !regexec(&m->pat, headers[i], 0, NULL, 0))
found = 1;
if(found)
return 0;
}
return 1;
}
/*
* Find the right service for a request
*/
SERVICE *
get_service(const LISTENER *lstn, const char *request, char **const headers)
{
SERVICE *svc;
for(svc = lstn->services; svc; svc = svc->next) {
if(svc->disabled)
continue;
if(match_service(svc, request, headers))
return svc;
}
/* try global services */
for(svc = services; svc; svc = svc->next) {
if(svc->disabled)
continue;
if(match_service(svc, request, headers))
return svc;
}
/* nothing matched */
return NULL;
}
/*
* extract the session key for a given request
*/
static int
get_REQUEST(char *res, const SERVICE *svc, const char *request)
{
int n, s;
regmatch_t matches[4];
if(regexec(&svc->sess_start, request, 4, matches, 0)) {
res[0] = '\0';
return 0;
}
s = matches[0].rm_eo;
if(regexec(&svc->sess_pat, request + s, 4, matches, 0)) {
res[0] = '\0';
return 0;
}
if((n = matches[1].rm_eo - matches[1].rm_so) > KEY_SIZE)
n = KEY_SIZE;
strncpy(res, request + s + matches[1].rm_so, n);
res[n] = '\0';
return 1;
}
static int
get_HEADERS(char *res, const SERVICE *svc, char **const headers)
{
int i, n, s;
regmatch_t matches[4];
/* this will match SESS_COOKIE, SESS_HEADER and SESS_BASIC */
res[0] = '\0';
for(i = 0; i < (MAXHEADERS - 1); i++) {
if(headers[i] == NULL)
continue;
if(regexec(&svc->sess_start, headers[i], 4, matches, 0))
continue;
s = matches[0].rm_eo;
if(regexec(&svc->sess_pat, headers[i] + s, 4, matches, 0))
continue;
if((n = matches[1].rm_eo - matches[1].rm_so) > KEY_SIZE)
n = KEY_SIZE;
strncpy(res, headers[i] + s + matches[1].rm_so, n);
res[n] = '\0';
}
return res[0] != '\0';
}
/*
* Pick a random back-end from a candidate list
*/
static BACKEND *
rand_backend(BACKEND *be, int pri)
{
while(be) {
if(!be->alive || be->disabled) {
be = be->next;
continue;
}
if((pri -= be->priority) < 0)
break;
be = be->next;
}
return be;
}
/*
* return a back-end based on a fixed hash value
* this is used for session_ttl < 0
*
* WARNING: the function may return different back-ends
* if the target back-end is disabled or not alive
*/
static BACKEND *
hash_backend(BACKEND *be, int abs_pri, char *key)
{
unsigned long hv;
BACKEND *res, *tb;
int pri;
hv = 2166136261;
while(*key)
hv = ((hv ^ *key++) * 16777619) & 0xFFFFFFFF;
pri = hv % abs_pri;
for(tb = be; tb; tb = tb->next)
if((pri -= tb->priority) < 0)
break;
if(!tb)
/* should NEVER happen */
return NULL;
for(res = tb; !res->alive || res->disabled; ) {
res = res->next;
if(res == NULL)
res = be;
if(res == tb)
/* NO back-end available */
return NULL;
}
return res;
}
/*
* Find the right back-end for a request
*/
BACKEND *
get_backend(SERVICE *const svc, const struct addrinfo *from_host, const char *request, char **const headers)
{
BACKEND *res;
char key[KEY_SIZE + 1];
int ret_val, no_be;
void *vp;
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "get_backend() lock: %s", strerror(ret_val));
no_be = (svc->tot_pri <= 0);
switch(svc->sess_type) {
case SESS_NONE:
/* choose one back-end randomly */
res = no_be? svc->emergency: rand_backend(svc->backends, random() % svc->tot_pri);
break;
case SESS_IP:
addr2str(key, KEY_SIZE, from_host, 1);
if(svc->sess_ttl < 0)
res = no_be? svc->emergency: hash_backend(svc->backends, svc->abs_pri, key);
else if((vp = t_find(svc->sessions, key)) == NULL) {
if(no_be)
res = svc->emergency;
else {
/* no session yet - create one */
res = rand_backend(svc->backends, random() % svc->tot_pri);
t_add(svc->sessions, key, &res, sizeof(res));
}
} else
memcpy(&res, vp, sizeof(res));
break;
case SESS_URL:
case SESS_PARM:
if(get_REQUEST(key, svc, request)) {
if(svc->sess_ttl < 0)
res = no_be? svc->emergency: hash_backend(svc->backends, svc->abs_pri, key);
else if((vp = t_find(svc->sessions, key)) == NULL) {
if(no_be)
res = svc->emergency;
else {
/* no session yet - create one */
res = rand_backend(svc->backends, random() % svc->tot_pri);
t_add(svc->sessions, key, &res, sizeof(res));
}
} else
memcpy(&res, vp, sizeof(res));
} else {
res = no_be? svc->emergency: rand_backend(svc->backends, random() % svc->tot_pri);
}
break;
default:
/* this works for SESS_BASIC, SESS_HEADER and SESS_COOKIE */
if(get_HEADERS(key, svc, headers)) {
if(svc->sess_ttl < 0)
res = no_be? svc->emergency: hash_backend(svc->backends, svc->abs_pri, key);
else if((vp = t_find(svc->sessions, key)) == NULL) {
if(no_be)
res = svc->emergency;
else {
/* no session yet - create one */
res = rand_backend(svc->backends, random() % svc->tot_pri);
t_add(svc->sessions, key, &res, sizeof(res));
}
} else
memcpy(&res, vp, sizeof(res));
} else {
res = no_be? svc->emergency: rand_backend(svc->backends, random() % svc->tot_pri);
}
break;
}
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "get_backend() unlock: %s", strerror(ret_val));
return res;
}
/*
* (for cookies/header only) possibly create session based on response headers
*/
void
upd_session(SERVICE *const svc, char **const headers, BACKEND *const be)
{
char key[KEY_SIZE + 1];
int ret_val;
if(svc->sess_type != SESS_HEADER && svc->sess_type != SESS_COOKIE)
return;
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "upd_session() lock: %s", strerror(ret_val));
if(get_HEADERS(key, svc, headers))
if(t_find(svc->sessions, key) == NULL)
t_add(svc->sessions, key, &be, sizeof(be));
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "upd_session() unlock: %s", strerror(ret_val));
return;
}
/*
* mark a backend host as dead/disabled; remove its sessions if necessary
* disable_only == 1: mark as disabled
* disable_only == 0: mark as dead, remove sessions
* disable_only == -1: mark as enabled
*/
void
kill_be(SERVICE *const svc, const BACKEND *be, const int disable_mode)
{
BACKEND *b;
int ret_val;
char buf[MAXBUF];
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "kill_be() lock: %s", strerror(ret_val));
svc->tot_pri = 0;
for(b = svc->backends; b; b = b->next) {
if(b == be)
switch(disable_mode) {
case BE_DISABLE:
b->disabled = 1;
str_be(buf, MAXBUF - 1, b);
logmsg(LOG_NOTICE, "(%lx) BackEnd %s disabled", pthread_self(), buf);
break;
case BE_KILL:
b->alive = 0;
str_be(buf, MAXBUF - 1, b);
logmsg(LOG_NOTICE, "(%lx) BackEnd %s dead (killed)", pthread_self(), buf);
t_clean(svc->sessions, &be, sizeof(be));
break;
case BE_ENABLE:
str_be(buf, MAXBUF - 1, b);
logmsg(LOG_NOTICE, "(%lx) BackEnd %s enabled", pthread_self(), buf);
b->disabled = 0;
break;
default:
logmsg(LOG_WARNING, "kill_be(): unknown mode %d", disable_mode);
break;
}
if(b->alive && !b->disabled)
svc->tot_pri += b->priority;
}
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "kill_be() unlock: %s", strerror(ret_val));
return;
}
/*
* Search for a host name, return the addrinfo for it
*/
int
get_host(char *const name, struct addrinfo *res, int ai_family)
{
struct addrinfo *chain, *ap;
struct addrinfo hints;
int ret_val;
#ifdef HAVE_INET_NTOP
memset (&hints, 0, sizeof(hints));
hints.ai_family = ai_family;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_CANONNAME;
if((ret_val = getaddrinfo(name, NULL, &hints, &chain)) == 0) {
#ifdef _AIX
ap = chain;
#else
for(ap = chain; ap != NULL; ap = ap->ai_next)
if(ap->ai_socktype == SOCK_STREAM)
break;
#endif
if(ap == NULL) {
freeaddrinfo(chain);
return EAI_NONAME;
}
*res = *ap;
if((res->ai_addr = (struct sockaddr *)malloc(ap->ai_addrlen)) == NULL) {
freeaddrinfo(chain);
return EAI_MEMORY;
}
memcpy(res->ai_addr, ap->ai_addr, ap->ai_addrlen);
freeaddrinfo(chain);
}
#else
#error "Pound requires getaddrinfo()"
#endif
return ret_val;
}
/*
* Find if a redirect needs rewriting
* In general we have two possibilities that require it:
* (1) if the redirect was done to the correct location with the wrong port
* (2) if the redirect was done to the back-end rather than the listener
*/
int
need_rewrite(const int rewr_loc, char *const location, char *const path, const char *v_host, const LISTENER *lstn, const BACKEND *be)
{
struct addrinfo addr;
struct sockaddr_in in_addr, be_addr;
struct sockaddr_in6 in6_addr, be6_addr;
regmatch_t matches[4];
char *proto, *host, *port, *cp, buf[MAXBUF];
/* check if rewriting is required at all */
if(rewr_loc == 0)
return 0;
/* applies only to INET/INET6 back-ends */
if(be->addr.ai_family != AF_INET && be->addr.ai_family != AF_INET6)
return 0;
/* split the location into its fields */
if(regexec(&LOCATION, location, 4, matches, 0))
return 0;
proto = location + matches[1].rm_so;
host = location + matches[2].rm_so;
if(location[matches[3].rm_so] == '/')
matches[3].rm_so++;
/* path is guaranteed to be large enough */
strcpy(path, location + matches[3].rm_so);
location[matches[1].rm_eo] = location[matches[2].rm_eo] = '\0';
if((port = strchr(host, ':')) != NULL)
*port++ = '\0';
/*
* Check if the location has the same address as the listener or the back-end
*/
memset(&addr, 0, sizeof(addr));
if(get_host(host, &addr, be->addr.ai_family))
return 0;
/*
* compare the back-end
*/
if(addr.ai_family != be->addr.ai_family) {
free(addr.ai_addr);
return 0;
}
if(addr.ai_family == AF_INET) {
memcpy(&in_addr, addr.ai_addr, sizeof(in_addr));
memcpy(&be_addr, be->addr.ai_addr, sizeof(be_addr));
if(port)
in_addr.sin_port = (in_port_t)htons(atoi(port));
else if(!strcasecmp(proto, "https"))
in_addr.sin_port = (in_port_t)htons(443);
else
in_addr.sin_port = (in_port_t)htons(80);
/*
* check if the Location points to the back-end
*/
if(memcmp(&be_addr.sin_addr.s_addr, &in_addr.sin_addr.s_addr, sizeof(in_addr.sin_addr.s_addr)) == 0
&& memcmp(&be_addr.sin_port, &in_addr.sin_port, sizeof(in_addr.sin_port)) == 0) {
free(addr.ai_addr);
return 1;
}
} else /* AF_INET6 */ {
memcpy(&in6_addr, addr.ai_addr, sizeof(in6_addr));
memcpy(&be6_addr, be->addr.ai_addr, sizeof(be6_addr));
if(port)
in6_addr.sin6_port = (in_port_t)htons(atoi(port));
else if(!strcasecmp(proto, "https"))
in6_addr.sin6_port = (in_port_t)htons(443);
else
in6_addr.sin6_port = (in_port_t)htons(80);
/*
* check if the Location points to the back-end
*/
if(memcmp(&be6_addr.sin6_addr.s6_addr, &in6_addr.sin6_addr.s6_addr, sizeof(in6_addr.sin6_addr.s6_addr)) == 0
&& memcmp(&be6_addr.sin6_port, &in6_addr.sin6_port, sizeof(in6_addr.sin6_port)) == 0) {
free(addr.ai_addr);
return 1;
}
}
/*
* compare the listener
*/
if(rewr_loc != 1 || addr.ai_family != lstn->addr.ai_family) {
free(addr.ai_addr);
return 0;
}
memset(buf, '\0', MAXBUF);
strncpy(buf, v_host, MAXBUF - 1);
if((cp = strchr(buf, ':')) != NULL)
*cp = '\0';
if(addr.ai_family == AF_INET) {
memcpy(&be_addr, lstn->addr.ai_addr, sizeof(be_addr));
/*
* check if the Location points to the Listener but with the wrong port or protocol
*/
if((memcmp(&be_addr.sin_addr.s_addr, &in_addr.sin_addr.s_addr, sizeof(in_addr.sin_addr.s_addr)) == 0
|| strcasecmp(host, buf) == 0)
&& (memcmp(&be_addr.sin_port, &in_addr.sin_port, sizeof(in_addr.sin_port)) != 0
|| strcasecmp(proto, lstn->ctx? "http": "https"))) {
free(addr.ai_addr);
return 1;
}
} else {
memcpy(&be6_addr, lstn->addr.ai_addr, sizeof(be6_addr));
/*
* check if the Location points to the Listener but with the wrong port or protocol
*/
if((memcmp(&be6_addr.sin6_addr.s6_addr, &in6_addr.sin6_addr.s6_addr, sizeof(in6_addr.sin6_addr.s6_addr)) == 0
|| strcasecmp(host, buf) == 0)
&& (memcmp(&be6_addr.sin6_port, &in6_addr.sin6_port, sizeof(in6_addr.sin6_port)) != 0
|| strcasecmp(proto, lstn->ctx? "http": "https"))) {
free(addr.ai_addr);
return 1;
}
}
free(addr.ai_addr);
return 0;
}
/*
* Non-blocking connect(). Does the same as connect(2) but ensures
* it will time-out after a much shorter time period SERVER_TO
*/
int
connect_nb(const int sockfd, const struct addrinfo *serv_addr, const int to)
{
int flags, res, error;
socklen_t len;
struct pollfd p;
if((flags = fcntl(sockfd, F_GETFL, 0)) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl GETFL failed: %s", pthread_self(), strerror(errno));
return -1;
}
if(fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl SETFL failed: %s", pthread_self(), strerror(errno));
return -1;
}
error = 0;
if((res = connect(sockfd, serv_addr->ai_addr, serv_addr->ai_addrlen)) < 0)
if(errno != EINPROGRESS) {
logmsg(LOG_WARNING, "(%lx) connect_nb: connect failed: %s", pthread_self(), strerror(errno));
return (-1);
}
if(res == 0) {
/* connect completed immediately (usually localhost) */
if(fcntl(sockfd, F_SETFL, flags) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl reSETFL failed: %s", pthread_self(), strerror(errno));
return -1;
}
return 0;
}
memset(&p, 0, sizeof(p));
p.fd = sockfd;
p.events = POLLOUT;
if((res = poll(&p, 1, to * 1000)) != 1) {
if(res == 0) {
/* timeout */
logmsg(LOG_WARNING, "(%lx) connect_nb: poll timed out", pthread_self());
errno = ETIMEDOUT;
} else
logmsg(LOG_WARNING, "(%lx) connect_nb: poll failed: %s", pthread_self(), strerror(errno));
return -1;
}
/* socket is writeable == operation completed */
len = sizeof(error);
if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, &len) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: getsockopt failed: %s", pthread_self(), strerror(errno));
return -1;
}
/* restore file status flags */
if(fcntl(sockfd, F_SETFL, flags) < 0) {
logmsg(LOG_WARNING, "(%lx) connect_nb: fcntl reSETFL failed: %s", pthread_self(), strerror(errno));
return -1;
}
if(error) {
/* getsockopt() shows an error */
errno = error;
logmsg(LOG_WARNING, "(%lx) connect_nb: error after getsockopt: %s", pthread_self(), strerror(errno));
return -1;
}
/* really connected */
return 0;
}
/*
* Check if dead hosts returned to life;
* runs every alive seconds
*/
static void
do_resurect(void)
{
LISTENER *lstn;
SERVICE *svc;
BACKEND *be;
struct addrinfo z_addr, *addr;
int sock, modified;
char buf[MAXBUF];
int ret_val;
/* check hosts still alive - HAport */
memset(&z_addr, 0, sizeof(z_addr));
for(lstn = listeners; lstn; lstn = lstn->next)
for(svc = lstn->services; svc; svc = svc->next)
for(be = svc->backends; be; be = be->next) {
if(be->be_type)
continue;
if(!be->alive)
/* already dead */
continue;
if(memcmp(&(be->ha_addr), &z_addr, sizeof(z_addr)) == 0)
/* no HA port */
continue;
/* try connecting */
switch(be->ha_addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
kill_be(svc, be, BE_KILL);
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
}
shutdown(sock, 2);
close(sock);
}
for(svc = services; svc; svc = svc->next)
for(be = svc->backends; be; be = be->next) {
if(be->be_type)
continue;
if(!be->alive)
/* already dead */
continue;
if(memcmp(&(be->ha_addr), &z_addr, sizeof(z_addr)) == 0)
/* no HA port */
continue;
/* try connecting */
switch(be->ha_addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
if(connect_nb(sock, &be->ha_addr, be->conn_to) != 0) {
kill_be(svc, be, BE_KILL);
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s is dead (HA)", buf);
}
shutdown(sock, 2);
close(sock);
}
/* check hosts alive again */
for(lstn = listeners; lstn; lstn = lstn->next)
for(svc = lstn->services; svc; svc = svc->next) {
for(modified = 0, be = svc->backends; be; be = be->next) {
be->resurrect = 0;
if(be->be_type)
continue;
if(be->alive)
continue;
if(memcmp(&(be->ha_addr), &z_addr, sizeof(z_addr)) == 0) {
switch(be->addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
addr = &be->addr;
} else {
switch(be->ha_addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
addr = &be->ha_addr;
}
if(connect_nb(sock, addr, be->conn_to) == 0) {
be->resurrect = 1;
modified = 1;
}
shutdown(sock, 2);
close(sock);
}
if(modified) {
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "do_resurect() lock: %s", strerror(ret_val));
svc->tot_pri = 0;
for(be = svc->backends; be; be = be->next) {
if(be->resurrect) {
be->alive = 1;
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s resurrect", buf);
}
if(be->alive && !be->disabled)
svc->tot_pri += be->priority;
}
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "do_resurect() unlock: %s", strerror(ret_val));
}
}
for(svc = services; svc; svc = svc->next) {
for(modified = 0, be = svc->backends; be; be = be->next) {
be->resurrect = 0;
if(be->be_type)
continue;
if(be->alive)
continue;
if(memcmp(&(be->ha_addr), &z_addr, sizeof(z_addr)) == 0) {
switch(be->addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
addr = &be->addr;
} else {
switch(be->ha_addr.ai_family) {
case AF_INET:
if((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_INET6:
if((sock = socket(PF_INET6, SOCK_STREAM, 0)) < 0)
continue;
break;
case AF_UNIX:
if((sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0)
continue;
break;
default:
continue;
}
addr = &be->ha_addr;
}
if(connect_nb(sock, addr, be->conn_to) == 0) {
be->resurrect = 1;
modified = 1;
}
shutdown(sock, 2);
close(sock);
}
if(modified) {
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "do_resurect() lock: %s", strerror(ret_val));
svc->tot_pri = 0;
for(be = svc->backends; be; be = be->next) {
if(be->resurrect) {
be->alive = 1;
str_be(buf, MAXBUF - 1, be);
logmsg(LOG_NOTICE, "BackEnd %s resurrect", buf);
}
if(be->alive && !be->disabled)
svc->tot_pri += be->priority;
}
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "do_resurect() unlock: %s", strerror(ret_val));
}
}
return;
}
/*
* Remove expired sessions
* runs every EXPIRE_TO seconds
*/
static void
do_expire(void)
{
LISTENER *lstn;
SERVICE *svc;
time_t cur_time;
int ret_val;
/* remove stale sessions */
cur_time = time(NULL);
for(lstn = listeners; lstn; lstn = lstn->next)
for(svc = lstn->services; svc; svc = svc->next)
if(svc->sess_type != SESS_NONE) {
if(ret_val = pthread_mutex_lock(&svc->mut)) {
logmsg(LOG_WARNING, "do_expire() lock: %s", strerror(ret_val));
continue;
}
t_expire(svc->sessions, cur_time - svc->sess_ttl);
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "do_expire() unlock: %s", strerror(ret_val));
}
for(svc = services; svc; svc = svc->next)
if(svc->sess_type != SESS_NONE) {
if(ret_val = pthread_mutex_lock(&svc->mut)) {
logmsg(LOG_WARNING, "do_expire() lock: %s", strerror(ret_val));
continue;
}
t_expire(svc->sessions, cur_time - svc->sess_ttl);
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "do_expire() unlock: %s", strerror(ret_val));
}
return;
}
static pthread_mutex_t RSA_mut; /* mutex for RSA keygen */
static RSA *RSA512_keys[N_RSA_KEYS]; /* ephemeral RSA keys */
static RSA *RSA1024_keys[N_RSA_KEYS]; /* ephemeral RSA keys */
/*
* return a pre-generated RSA key
*/
RSA *
RSA_tmp_callback(/* not used */SSL *ssl, /* not used */int is_export, int keylength)
{
RSA *res;
int ret_val;
if(ret_val = pthread_mutex_lock(&RSA_mut))
logmsg(LOG_WARNING, "RSA_tmp_callback() lock: %s", strerror(ret_val));
res = (keylength <= 512)? RSA512_keys[rand() % N_RSA_KEYS]: RSA1024_keys[rand() % N_RSA_KEYS];
if(ret_val = pthread_mutex_unlock(&RSA_mut))
logmsg(LOG_WARNING, "RSA_tmp_callback() unlock: %s", strerror(ret_val));
return res;
}
/*
* Periodically regenerate ephemeral RSA keys
* runs every T_RSA_KEYS seconds
*/
static void
do_RSAgen(void)
{
int n, ret_val;
RSA *t_RSA512_keys[N_RSA_KEYS];
RSA *t_RSA1024_keys[N_RSA_KEYS];
for(n = 0; n < N_RSA_KEYS; n++) {
t_RSA512_keys[n] = RSA_generate_key(512, RSA_F4, NULL, NULL);
t_RSA1024_keys[n] = RSA_generate_key(1024, RSA_F4, NULL, NULL);
}
if(ret_val = pthread_mutex_lock(&RSA_mut))
logmsg(LOG_WARNING, "thr_RSAgen() lock: %s", strerror(ret_val));
for(n = 0; n < N_RSA_KEYS; n++) {
RSA_free(RSA512_keys[n]);
RSA512_keys[n] = t_RSA512_keys[n];
RSA_free(RSA1024_keys[n]);
RSA1024_keys[n] = t_RSA1024_keys[n];
}
if(ret_val = pthread_mutex_unlock(&RSA_mut))
logmsg(LOG_WARNING, "thr_RSAgen() unlock: %s", strerror(ret_val));
return;
}
#include "dh512.h"
#if DH_LEN == 1024
#include "dh1024.h"
static DH *DH512_params, *DH1024_params;
DH *
DH_tmp_callback(/* not used */SSL *s, /* not used */int is_export, int keylength)
{
return keylength == 512? DH512_params: DH1024_params;
}
#else
#include "dh2048.h"
static DH *DH512_params, *DH2048_params;
DH *
DH_tmp_callback(/* not used */SSL *s, /* not used */int is_export, int keylength)
{
return keylength == 512? DH512_params: DH2048_params;
}
#endif
static time_t last_RSA, last_alive, last_expire;
/*
* initialise the timer functions:
* - RSA_mut and keys
*/
void
init_timer(void)
{
int n;
last_RSA = last_alive = last_expire = time(NULL);
/*
* Pre-generate ephemeral RSA keys
*/
for(n = 0; n < N_RSA_KEYS; n++) {
if((RSA512_keys[n] = RSA_generate_key(512, RSA_F4, NULL, NULL)) == NULL) {
logmsg(LOG_WARNING,"RSA_generate(%d, 512) failed", n);
return;
}
if((RSA1024_keys[n] = RSA_generate_key(1024, RSA_F4, NULL, NULL)) == NULL) {
logmsg(LOG_WARNING,"RSA_generate(%d, 1024) failed", n);
return;
}
}
/* pthread_mutex_init() always returns 0 */
pthread_mutex_init(&RSA_mut, NULL);
DH512_params = get_dh512();
#if DH_LEN == 1024
DH1024_params = get_dh1024();
#else
DH2048_params = get_dh2048();
#endif
return;
}
/*
* run timed functions:
* - RSAgen every T_RSA_KEYS seconds
* - resurect every alive_to seconds
* - expire every EXPIRE_TO seconds
*/
void *
thr_timer(void *arg)
{
time_t last_time, cur_time;
int n_wait, n_remain;
n_wait = EXPIRE_TO;
if(n_wait > alive_to)
n_wait = alive_to;
if(n_wait > T_RSA_KEYS)
n_wait = T_RSA_KEYS;
for(last_time = time(NULL) - n_wait;;) {
cur_time = time(NULL);
if((n_remain = n_wait - (cur_time - last_time)) > 0)
sleep(n_remain);
last_time = time(NULL);
if((last_time - last_RSA) >= T_RSA_KEYS) {
last_RSA = time(NULL);
do_RSAgen();
}
if((last_time - last_alive) >= alive_to) {
last_alive = time(NULL);
do_resurect();
}
if((last_time - last_expire) >= EXPIRE_TO) {
last_expire = time(NULL);
do_expire();
}
}
}
typedef struct {
int control_sock;
BACKEND *backends;
} DUMP_ARG;
static void
t_dump_doall_arg(TABNODE *t, DUMP_ARG *arg)
{
BACKEND *be, *bep;
int n_be, sz;
memcpy(&bep, t->content, sizeof(bep));
for(n_be = 0, be = arg->backends; be; be = be->next, n_be++)
if(be == bep)
break;
if(!be)
/* should NEVER happen */
n_be = 0;
(void)write(arg->control_sock, t, sizeof(TABNODE));
(void)write(arg->control_sock, &n_be, sizeof(n_be));
sz = strlen(t->key);
(void)write(arg->control_sock, &sz, sizeof(sz));
(void)write(arg->control_sock, t->key, sz);
return;
}
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
IMPLEMENT_LHASH_DOALL_ARG_FN(t_dump, TABNODE, DUMP_ARG)
#else
#define t_dump t_dump_doall_arg
IMPLEMENT_LHASH_DOALL_ARG_FN(t_dump, TABNODE *, DUMP_ARG *)
#endif
/*
* write sessions to the control socket
*/
static void
dump_sess(const int control_sock, LHASH_OF(TABNODE) *const sess, BACKEND *const backends)
{
DUMP_ARG a;
a.control_sock = control_sock;
a.backends = backends;
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
LHM_lh_doall_arg(TABNODE, sess, LHASH_DOALL_ARG_FN(t_dump), DUMP_ARG, &a);
#else
lh_doall_arg(sess, LHASH_DOALL_ARG_FN(t_dump), &a);
#endif
return;
}
/*
* given a command, select a listener
*/
static LISTENER *
sel_lstn(const CTRL_CMD *cmd)
{
LISTENER *lstn;
int i;
if(cmd->listener < 0)
return NULL;
for(i = 0, lstn = listeners; lstn && i < cmd->listener; i++, lstn = lstn->next)
;
return lstn;
}
/*
* given a command, select a service
*/
static SERVICE *
sel_svc(const CTRL_CMD *cmd)
{
SERVICE *svc;
LISTENER *lstn;
int i;
if(cmd->listener < 0) {
svc = services;
} else {
if((lstn = sel_lstn(cmd)) == NULL)
return NULL;
svc = lstn->services;
}
for(i = 0; svc && i < cmd->service; i++, svc = svc->next)
;
return svc;
}
/*
* given a command, select a back-end
*/
static BACKEND *
sel_be(const CTRL_CMD *cmd)
{
BACKEND *be;
SERVICE *svc;
int i;
if((svc = sel_svc(cmd)) == NULL)
return NULL;
for(i = 0, be = svc->backends; be && i < cmd->backend; i++, be = be->next)
;
return be;
}
/*
* The controlling thread
* listens to client requests and calls the appropriate functions
*/
void *
thr_control(void *arg)
{
CTRL_CMD cmd;
struct sockaddr sa;
int ctl, dummy, n, ret_val;
LISTENER *lstn, dummy_lstn;
SERVICE *svc, dummy_svc;
BACKEND *be, dummy_be;
TABNODE dummy_sess;
struct pollfd polls;
/* just to be safe */
if(control_sock < 0)
return NULL;
memset(&dummy_lstn, 0, sizeof(dummy_lstn));
dummy_lstn.disabled = -1;
memset(&dummy_svc, 0, sizeof(dummy_svc));
dummy_svc.disabled = -1;
memset(&dummy_be, 0, sizeof(dummy_be));
dummy_be.disabled = -1;
memset(&dummy_sess, 0, sizeof(dummy_sess));
dummy_sess.content = NULL;
dummy = sizeof(sa);
for(;;) {
polls.fd = control_sock;
polls.events = POLLIN | POLLPRI;
polls.revents = 0;
if(poll(&polls, 1, -1) < 0) {
logmsg(LOG_WARNING, "thr_control() poll: %s", strerror(errno));
continue;
}
if((ctl = accept(control_sock, &sa, (socklen_t *)&dummy)) < 0) {
logmsg(LOG_WARNING, "thr_control() accept: %s", strerror(errno));
continue;
}
if(read(ctl, &cmd, sizeof(cmd)) != sizeof(cmd)) {
logmsg(LOG_WARNING, "thr_control() read: %s", strerror(errno));
continue;
}
switch(cmd.cmd) {
case CTRL_LST:
/* logmsg(LOG_INFO, "thr_control() list"); */
n = get_thr_qlen();
(void)write(ctl, (void *)&n, sizeof(n));
for(lstn = listeners; lstn; lstn = lstn->next) {
(void)write(ctl, (void *)lstn, sizeof(LISTENER));
(void)write(ctl, lstn->addr.ai_addr, lstn->addr.ai_addrlen);
for(svc = lstn->services; svc; svc = svc->next) {
(void)write(ctl, (void *)svc, sizeof(SERVICE));
for(be = svc->backends; be; be = be->next) {
(void)write(ctl, (void *)be, sizeof(BACKEND));
(void)write(ctl, be->addr.ai_addr, be->addr.ai_addrlen);
if(be->ha_addr.ai_addrlen > 0)
(void)write(ctl, be->ha_addr.ai_addr, be->ha_addr.ai_addrlen);
}
(void)write(ctl, (void *)&dummy_be, sizeof(BACKEND));
if(dummy = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() lock: %s", strerror(dummy));
else {
dump_sess(ctl, svc->sessions, svc->backends);
if(dummy = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() unlock: %s", strerror(dummy));
}
(void)write(ctl, (void *)&dummy_sess, sizeof(TABNODE));
}
(void)write(ctl, (void *)&dummy_svc, sizeof(SERVICE));
}
(void)write(ctl, (void *)&dummy_lstn, sizeof(LISTENER));
for(svc = services; svc; svc = svc->next) {
(void)write(ctl, (void *)svc, sizeof(SERVICE));
for(be = svc->backends; be; be = be->next) {
(void)write(ctl, (void *)be, sizeof(BACKEND));
(void)write(ctl, be->addr.ai_addr, be->addr.ai_addrlen);
if(be->ha_addr.ai_addrlen > 0)
(void)write(ctl, be->ha_addr.ai_addr, be->ha_addr.ai_addrlen);
}
(void)write(ctl, (void *)&dummy_be, sizeof(BACKEND));
if(dummy = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() lock: %s", strerror(dummy));
else {
dump_sess(ctl, svc->sessions, svc->backends);
if(dummy = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() unlock: %s", strerror(dummy));
}
(void)write(ctl, (void *)&dummy_sess, sizeof(TABNODE));
}
(void)write(ctl, (void *)&dummy_svc, sizeof(SERVICE));
break;
case CTRL_EN_LSTN:
if((lstn = sel_lstn(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad listener %d", cmd.listener);
else
lstn->disabled = 0;
break;
case CTRL_DE_LSTN:
if((lstn = sel_lstn(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad listener %d", cmd.listener);
else
lstn->disabled = 1;
break;
case CTRL_EN_SVC:
if((svc = sel_svc(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
else
svc->disabled = 0;
break;
case CTRL_DE_SVC:
if((svc = sel_svc(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
else
svc->disabled = 1;
break;
case CTRL_EN_BE:
if((svc = sel_svc(&cmd)) == NULL) {
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
break;
}
if((be = sel_be(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad backend %d/%d/%d", cmd.listener, cmd.service, cmd.backend);
else
kill_be(svc, be, BE_ENABLE);
break;
case CTRL_DE_BE:
if((svc = sel_svc(&cmd)) == NULL) {
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
break;
}
if((be = sel_be(&cmd)) == NULL)
logmsg(LOG_INFO, "thr_control() bad backend %d/%d/%d", cmd.listener, cmd.service, cmd.backend);
else
kill_be(svc, be, BE_DISABLE);
break;
case CTRL_ADD_SESS:
if((svc = sel_svc(&cmd)) == NULL) {
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
break;
}
if((be = sel_be(&cmd)) == NULL) {
logmsg(LOG_INFO, "thr_control() bad back-end %d/%d", cmd.listener, cmd.service);
break;
}
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() add session lock: %s", strerror(ret_val));
t_add(svc->sessions, cmd.key, &be, sizeof(be));
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "thoriginalfiler_control() add session unlock: %s", strerror(ret_val));
break;
case CTRL_DEL_SESS:
if((svc = sel_svc(&cmd)) == NULL) {
logmsg(LOG_INFO, "thr_control() bad service %d/%d", cmd.listener, cmd.service);
break;
}
if(ret_val = pthread_mutex_lock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() del session lock: %s", strerror(ret_val));
t_remove(svc->sessions, cmd.key);
if(ret_val = pthread_mutex_unlock(&svc->mut))
logmsg(LOG_WARNING, "thr_control() del session unlock: %s", strerror(ret_val));
break;
default:
logmsg(LOG_WARNING, "thr_control() unknown command");
break;
}
close(ctl);
}
}
void
SSLINFO_callback(const SSL *ssl, int where, int rc)
{
RENEG_STATE *reneg_state;
/* Get our thr_arg where we're tracking this connection info */
if((reneg_state = (RENEG_STATE *)SSL_get_app_data(ssl)) == NULL)
return;
/* If we're rejecting renegotiations, move to ABORT if Client Hello is being read. */
if((where & SSL_CB_ACCEPT_LOOP) && *reneg_state == RENEG_REJECT) {
int state;
state = SSL_get_state(ssl);
if (state == SSL3_ST_SR_CLNT_HELLO_A || state == SSL23_ST_SR_CLNT_HELLO_A) {
*reneg_state = RENEG_ABORT;
logmsg(LOG_WARNING,"rejecting client initiated renegotiation");
}
} else if(where & SSL_CB_HANDSHAKE_DONE && *reneg_state == RENEG_INIT) {
// Reject any followup renegotiations
*reneg_state = RENEG_REJECT;
}
}
Pound-2.8/pound.c 0000664 0001750 0001750 00000042540 13275266545 013007 0 ustar roseg roseg /*
* Pound - the reverse-proxy load-balancer
* Copyright (C) 2002-2010 Apsis GmbH
*
* This file is part of Pound.
*
* Pound is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* Pound is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Contact information:
* Apsis GmbH
* P.O.Box
* 8707 Uetikon am See
* Switzerland
* EMail: roseg@apsis.ch
*/
#include "pound.h"
/* common variables */
char *user, /* user to run as */
*group, /* group to run as */
*root_jail, /* directory to chroot to */
*pid_name, /* file to record pid in */
*ctrl_name; /* control socket name */
int alive_to, /* check interval for resurrection */
anonymise, /* anonymise client address */
daemonize, /* run as daemon */
log_facility, /* log facility to use */
print_log, /* print log messages to stdout/stderr */
grace, /* grace period before shutdown */
control_sock; /* control socket */
SERVICE *services; /* global services (if any) */
LISTENER *listeners; /* all available listeners */
regex_t HEADER, /* Allowed header */
CHUNK_HEAD, /* chunk header line */
RESP_SKIP, /* responses for which we skip response */
RESP_IGN, /* responses for which we ignore content */
LOCATION, /* the host we are redirected to */
AUTHORIZATION; /* the Authorisation header */
static int shut_down = 0;
#ifndef SOL_TCP
/* for systems without the definition */
int SOL_TCP;
#endif
/* worker pid */
static pid_t son = 0;
/*
* OpenSSL thread support stuff
*/
static pthread_mutex_t *l_array;
static void
l_init(void)
{
int i, n_locks;
n_locks = CRYPTO_num_locks();
if((l_array = (pthread_mutex_t *)calloc(n_locks, sizeof(pthread_mutex_t))) == NULL) {
logmsg(LOG_ERR, "lock init: out of memory - aborted...");
exit(1);
}
for(i = 0; i < n_locks; i++)
/* pthread_mutex_init() always returns 0 */
pthread_mutex_init(&l_array[i], NULL);
return;
}
static void
l_lock(const int mode, const int n, /* unused */ const char *file, /* unused */ int line)
{
int ret_val;
if(mode & CRYPTO_LOCK) {
if(ret_val = pthread_mutex_lock(&l_array[n]))
logmsg(LOG_ERR, "l_lock lock(): %s", strerror(ret_val));
} else {
if(ret_val = pthread_mutex_unlock(&l_array[n]))
logmsg(LOG_ERR, "l_lock unlock(): %s", strerror(ret_val));
}
return;
}
static unsigned long
l_id(void)
{
return (unsigned long)pthread_self();
}
/*
* work queue stuff
*/
static thr_arg *first = NULL, *last = NULL;
static pthread_cond_t arg_cond;
static pthread_mutex_t arg_mut;
int numthreads;
static void
init_thr_arg(void)
{
pthread_cond_init(&arg_cond, NULL);
pthread_mutex_init(&arg_mut, NULL);
return;
}
/*
* add a request to the queue
*/
int
put_thr_arg(thr_arg *arg)
{
thr_arg *res;
if((res = malloc(sizeof(thr_arg))) == NULL) {
logmsg(LOG_WARNING, "thr_arg malloc");
return -1;
}
memcpy(res, arg, sizeof(thr_arg));
res->next = NULL;
(void)pthread_mutex_lock(&arg_mut);
if(last == NULL)
first = last = res;
else {
last->next = res;
last = last->next;
}
(void)pthread_mutex_unlock(&arg_mut);
pthread_cond_signal(&arg_cond);
return 0;
}
/*
* get a request from the queue
*/
thr_arg *
get_thr_arg(void)
{
thr_arg *res;
(void)pthread_mutex_lock(&arg_mut);
if(first == NULL)
(void)pthread_cond_wait(&arg_cond, &arg_mut);
if((res = first) != NULL)
if((first = first->next) == NULL)
last = NULL;
(void)pthread_mutex_unlock(&arg_mut);
if(first != NULL)
pthread_cond_signal(&arg_cond);
return res;
}
/*
* get the current queue length
*/
int
get_thr_qlen(void)
{
int res;
thr_arg *tap;
(void)pthread_mutex_lock(&arg_mut);
for(res = 0, tap = first; tap != NULL; tap = tap->next, res++)
;
(void)pthread_mutex_unlock(&arg_mut);
return res;
}
/*
* handle SIGTERM/SIGQUIT - exit
*/
static RETSIGTYPE
h_term(const int sig)
{
logmsg(LOG_NOTICE, "received signal %d - exiting...", sig);
if(son > 0)
kill(son, sig);
if(ctrl_name != NULL)
(void)unlink(ctrl_name);
exit(0);
}
/*
* handle SIGHUP/SIGINT - exit after grace period
*/
static RETSIGTYPE
h_shut(const int sig)
{
int status;
LISTENER *lstn;
logmsg(LOG_NOTICE, "received signal %d - shutting down...", sig);
if(son > 0) {
for(lstn = listeners; lstn; lstn = lstn->next)
close(lstn->sock);
kill(son, sig);
(void)wait(&status);
if(ctrl_name != NULL)
(void)unlink(ctrl_name);
exit(0);
} else
shut_down = 1;
}
/*
* Pound: the reverse-proxy/load-balancer
*
* Arguments:
* -f config_file configuration file - exclusive of other flags
*/
int
main(const int argc, char **argv)
{
int n_listeners, i, clnt_length, clnt;
struct pollfd *polls;
LISTENER *lstn;
pthread_t thr;
pthread_attr_t attr;
struct sched_param sp;
uid_t user_id;
gid_t group_id;
FILE *fpid;
struct sockaddr_storage clnt_addr;
char tmp[MAXBUF];
#ifndef SOL_TCP
struct protoent *pe;
#endif
print_log = 0;
(void)umask(077);
control_sock = -1;
log_facility = -1;
logmsg(LOG_NOTICE, "starting...");
signal(SIGHUP, h_shut);
signal(SIGINT, h_shut);
signal(SIGTERM, h_term);
signal(SIGQUIT, h_term);
signal(SIGPIPE, SIG_IGN);
srandom(getpid());
/* SSL stuff */
SSL_load_error_strings();
SSL_library_init();
OpenSSL_add_all_algorithms();
l_init();
init_thr_arg();
CRYPTO_set_id_callback(l_id);
CRYPTO_set_locking_callback(l_lock);
init_timer();
/* Disable SSL Compression for OpenSSL pre-1.0. 1.0 is handled with an option in config.c */
#if OPENSSL_VERSION_NUMBER >= 0x00907000L
#ifndef SSL_OP_NO_COMPRESSION
{
int i,n;
STACK_OF(SSL_COMP) *ssl_comp_methods;
ssl_comp_methods = SSL_COMP_get_compression_methods();
n = sk_SSL_COMP_num(ssl_comp_methods);
for(i=n-1; i>=0; i--) {
sk_SSL_COMP_delete(ssl_comp_methods, i);
}
}
#endif
#endif
/* prepare regular expressions */
if(regcomp(&HEADER, "^([a-z0-9!#$%&'*+.^_`|~-]+):[ \t]*(.*)[ \t]*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&CHUNK_HEAD, "^([0-9a-f]+).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RESP_SKIP, "^HTTP/1.1 100.*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&RESP_IGN, "^HTTP/1.[01] (10[1-9]|1[1-9][0-9]|204|30[456]).*$", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&LOCATION, "(http|https)://([^/]+)(.*)", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
|| regcomp(&AUTHORIZATION, "Authorization:[ \t]*Basic[ \t]*\"?([^ \t]*)\"?[ \t]*", REG_ICASE | REG_NEWLINE | REG_EXTENDED)
) {
logmsg(LOG_ERR, "bad essential Regex - aborted");
exit(1);
}
#ifndef SOL_TCP
/* for systems without the definition */
if((pe = getprotobyname("tcp")) == NULL) {
logmsg(LOG_ERR, "missing TCP protocol");
exit(1);
}
SOL_TCP = pe->p_proto;
#endif
/* read config */
config_parse(argc, argv);
if(log_facility != -1)
openlog("pound", LOG_CONS | LOG_NDELAY, LOG_DAEMON);
if(ctrl_name != NULL) {
struct sockaddr_un ctrl;
memset(&ctrl, 0, sizeof(ctrl));
ctrl.sun_family = AF_UNIX;
strncpy(ctrl.sun_path, ctrl_name, sizeof(ctrl.sun_path) - 1);
(void)unlink(ctrl.sun_path);
if((control_sock = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
logmsg(LOG_ERR, "Control \"%s\" create: %s", ctrl.sun_path, strerror(errno));
exit(1);
}
if(bind(control_sock, (struct sockaddr *)&ctrl, (socklen_t)sizeof(ctrl)) < 0) {
logmsg(LOG_ERR, "Control \"%s\" bind: %s", ctrl.sun_path, strerror(errno));
exit(1);
}
listen(control_sock, 512);
}
/* open listeners */
for(lstn = listeners, n_listeners = 0; lstn; lstn = lstn->next, n_listeners++) {
int opt;
/* prepare the socket */
if((lstn->sock = socket(lstn->addr.ai_family == AF_INET? PF_INET: PF_INET6, SOCK_STREAM, 0)) < 0) {
addr2str(tmp, MAXBUF - 1, &lstn->addr, 0);
logmsg(LOG_ERR, "HTTP socket %s create: %s - aborted", tmp, strerror(errno));
exit(1);
}
opt = 1;
setsockopt(lstn->sock, SOL_SOCKET, SO_REUSEADDR, (void *)&opt, sizeof(opt));
if(bind(lstn->sock, lstn->addr.ai_addr, (socklen_t)lstn->addr.ai_addrlen) < 0) {
addr2str(tmp, MAXBUF - 1, &lstn->addr, 0);
logmsg(LOG_ERR, "HTTP socket bind %s: %s - aborted", tmp, strerror(errno));
exit(1);
}
listen(lstn->sock, 512);
}
/* alloc the poll structures */
if((polls = (struct pollfd *)calloc(n_listeners, sizeof(struct pollfd))) == NULL) {
logmsg(LOG_ERR, "Out of memory for poll - aborted");
exit(1);
}
for(lstn = listeners, i = 0; lstn; lstn = lstn->next, i++)
polls[i].fd = lstn->sock;
/* set uid if necessary */
if(user) {
struct passwd *pw;
if((pw = getpwnam(user)) == NULL) {
logmsg(LOG_ERR, "no such user %s - aborted", user);
exit(1);
}
user_id = pw->pw_uid;
}
/* set gid if necessary */
if(group) {
struct group *gr;
if((gr = getgrnam(group)) == NULL) {
logmsg(LOG_ERR, "no such group %s - aborted", group);
exit(1);
}
group_id = gr->gr_gid;
}
/* Turn off verbose messages (if necessary) */
print_log = 0;
if(daemonize) {
/* daemonize - make ourselves a subprocess. */
switch (fork()) {
case 0:
if(log_facility != -1) {
close(0);
close(1);
close(2);
}
break;
case -1:
logmsg(LOG_ERR, "fork: %s - aborted", strerror(errno));
exit(1);
default:
exit(0);
}
#ifdef HAVE_SETSID
(void) setsid();
#endif
}
/* record pid in file */
if((fpid = fopen(pid_name, "wt")) != NULL) {
fprintf(fpid, "%d\n", getpid());
fclose(fpid);
} else
logmsg(LOG_NOTICE, "Create \"%s\": %s", pid_name, strerror(errno));
/* chroot if necessary */
if(root_jail) {
if(chroot(root_jail)) {
logmsg(LOG_ERR, "chroot: %s - aborted", strerror(errno));
exit(1);
}
if(chdir("/")) {
logmsg(LOG_ERR, "chroot/chdir: %s - aborted", strerror(errno));
exit(1);
}
}
if(group)
if(setgid(group_id) || setegid(group_id)) {
logmsg(LOG_ERR, "setgid: %s - aborted", strerror(errno));
exit(1);
}
if(user)
if(setuid(user_id) || seteuid(user_id)) {
logmsg(LOG_ERR, "setuid: %s - aborted", strerror(errno));
exit(1);
}
/* split off into monitor and working process if necessary */
for(;;) {
#ifdef UPER
if((son = fork()) > 0) {
int status;
(void)wait(&status);
if(WIFEXITED(status))
logmsg(LOG_ERR, "MONITOR: worker exited normally %d, restarting...", WEXITSTATUS(status));
else if(WIFSIGNALED(status))
logmsg(LOG_ERR, "MONITOR: worker exited on signal %d, restarting...", WTERMSIG(status));
else
logmsg(LOG_ERR, "MONITOR: worker exited (stopped?) %d, restarting...", status);
} else if (son == 0) {
#endif
/* thread stuff */
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
#ifdef NEED_STACK
/* set new stack size - necessary for OpenBSD/FreeBSD and Linux NPTL */
if(pthread_attr_setstacksize(&attr, 1 << 18)) {
logmsg(LOG_ERR, "can't set stack size - aborted");
exit(1);
}
#endif
/* start timer */
if(pthread_create(&thr, &attr, thr_timer, NULL)) {
logmsg(LOG_ERR, "create thr_resurect: %s - aborted", strerror(errno));
exit(1);
}
/* start the controlling thread (if needed) */
if(control_sock >= 0 && pthread_create(&thr, &attr, thr_control, NULL)) {
logmsg(LOG_ERR, "create thr_control: %s - aborted", strerror(errno));
exit(1);
}
/* pause to make sure the service threads were started */
sleep(1);
/* create the worker threads */
for(i = 0; i < numthreads; i++)
if(pthread_create(&thr, &attr, thr_http, NULL)) {
logmsg(LOG_ERR, "create thr_http: %s - aborted", strerror(errno));
exit(1);
}
/* pause to make sure at least some of the worker threads were started */
sleep(1);
/* and start working */
for(;;) {
if(shut_down) {
logmsg(LOG_NOTICE, "shutting down...");
for(lstn = listeners; lstn; lstn = lstn->next)
close(lstn->sock);
if(grace > 0) {
sleep(grace);
logmsg(LOG_NOTICE, "grace period expired - exiting...");
}
if(ctrl_name != NULL)
(void)unlink(ctrl_name);
exit(0);
}
for(lstn = listeners, i = 0; i < n_listeners; lstn = lstn->next, i++) {
polls[i].events = POLLIN | POLLPRI;
polls[i].revents = 0;
}
if(poll(polls, n_listeners, -1) < 0) {
logmsg(LOG_WARNING, "poll: %s", strerror(errno));
} else {
for(lstn = listeners, i = 0; lstn; lstn = lstn->next, i++) {
if(polls[i].revents & (POLLIN | POLLPRI)) {
memset(&clnt_addr, 0, sizeof(clnt_addr));
clnt_length = sizeof(clnt_addr);
if((clnt = accept(lstn->sock, (struct sockaddr *)&clnt_addr,
(socklen_t *)&clnt_length)) < 0) {
logmsg(LOG_WARNING, "HTTP accept: %s", strerror(errno));
} else if(((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET
|| ((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET6) {
thr_arg arg;
if(lstn->disabled) {
/*
addr2str(tmp, MAXBUF - 1, &clnt_addr, 1);
logmsg(LOG_WARNING, "HTTP disabled listener from %s", tmp);
*/
close(clnt);
}
arg.sock = clnt;
arg.lstn = lstn;
if((arg.from_host.ai_addr = (struct sockaddr *)malloc(clnt_length)) == NULL) {
logmsg(LOG_WARNING, "HTTP arg address: malloc");
close(clnt);
continue;
}
memcpy(arg.from_host.ai_addr, &clnt_addr, clnt_length);
arg.from_host.ai_addrlen = clnt_length;
if(((struct sockaddr_in *)&clnt_addr)->sin_family == AF_INET)
arg.from_host.ai_family = AF_INET;
else
arg.from_host.ai_family = AF_INET6;
if(put_thr_arg(&arg))
close(clnt);
} else {
/* may happen on FreeBSD, I am told */
logmsg(LOG_WARNING, "HTTP connection prematurely closed by peer");
close(clnt);
}
}
}
}
}
#ifdef UPER
} else {
/* failed to spawn son */
logmsg(LOG_ERR, "Can't fork worker (%s) - aborted", strerror(errno));
exit(1);
}
#endif
}
}