You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rs...@hyperreal.org on 1998/03/31 17:46:18 UTC

cvs commit: apache-1.3/src/support apxs.8 apxs.pl Makefile.tmpl

rse         98/03/31 07:46:17

  Modified:    .        STATUS configure Makefile.tmpl
               src      CHANGES
               src/support Makefile.tmpl
  Added:       src/support apxs.8 apxs.pl
  Log:
  The new APache eXtenSion (apxs) support tool which can be used for OFF-SOURCE
  extending Apache via the dynamic shared object (DSO) mechanism provided by
  mod_so.
  
  Revision  Changes    Path
  1.250     +1 -0      apache-1.3/STATUS
  
  Index: STATUS
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/STATUS,v
  retrieving revision 1.249
  retrieving revision 1.250
  diff -u -r1.249 -r1.250
  --- STATUS	1998/03/31 12:52:01	1.249
  +++ STATUS	1998/03/31 15:46:08	1.250
  @@ -131,6 +131,7 @@
       * Ralf's add of the new Apache Autoconf-style Interface (APACI)
       * Rainer Scherg's fix for CONNECT proxy support: #1326, #1573, #1942
       * Ken's reworking of the Apache LICENSE
  +    * Ralf's APache eXtenSion for easy "off-source" extending Apache via DSO
   
   Available Patches:
   
  
  
  
  1.4       +10 -1     apache-1.3/configure
  
  Index: configure
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/configure,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- configure	1998/03/31 12:52:02	1.3
  +++ configure	1998/03/31 15:46:10	1.4
  @@ -139,6 +139,7 @@
   localstatedir='$prefix/var'
   localstatesubdir_run='run'
   localstatesubdir_logs='logs'
  +includedir='$prefix/include'
   
   #   check and debug
   layout=0
  @@ -273,6 +274,7 @@
               echo " --sysconfdir=DIR       install configuration files in DIR   [PREFIX/etc]"
               echo " --datadir=DIR          install read-only  data files in DIR [PREFIX/share]"
               echo " --localstatedir=DIR    install modifiable data files in DIR [PREFIX/var]"
  +            echo " --includedir=DIR       install includes files in DIR        [PREFIX/include]"
               echo " --compat               install with old Apache 1.2 installation paths"
               echo ""
               echo "Configuration options:"
  @@ -325,6 +327,9 @@
           --localstatedir=*) 
               localstatedir="$apc_optarg" 
               ;;
  +        --includedir=*)       
  +            includedir="$apc_optarg"       
  +            ;;
           --compat) 
               prefix='/usr/local/apache'
               exec_prefix='$prefix'
  @@ -337,6 +342,7 @@
               localstatedir='$prefix'
               localstatesubdir_run='logs'
               localstatesubdir_logs='logs'
  +            includedir='$prefix/include'
               ;;
           --add-module=*) 
               file="$apc_optarg"
  @@ -576,7 +582,8 @@
   ##
   IFS=' '
   for var in prefix exec_prefix bindir sbindir \
  -           libexecdir mandir sysconfdir datadir localstatedir; do
  +           libexecdir mandir sysconfdir datadir \
  +           localstatedir includedir; do
       eval "val=\$$var";
       val=`echo $val | sed -e 's:/*$::'`
       eval "$var=\"$val\""
  @@ -619,6 +626,7 @@
       echo "           sysconfdir: $sysconfdir" 
       echo "              datadir: $datadir" 
       echo "        localstatedir: $localstatedir" 
  +    echo "           includedir: $includedir" 
       echo ""
       echo "Compilation paths:"
       echo "           HTTPD_ROOT: $prefix"
  @@ -660,6 +668,7 @@
   -e "s%@localstatedir@%$localstatedir%g" \
   -e "s%@localstatesubdir_run@%$localstatesubdir_run%g" \
   -e "s%@localstatesubdir_logs@%$localstatesubdir_logs%g" \
  +-e "s%@includedir@%$includedir%g" \
   -e "s%@suexec@%$suexec%g" \
   -e "s%@suexec_caller@%$suexec_caller%g" \
   -e "s%@suexec_userdir@%$suexec_userdir%g"
  
  
  
  1.4       +21 -2     apache-1.3/Makefile.tmpl
  
  Index: Makefile.tmpl
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/Makefile.tmpl,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- Makefile.tmpl	1998/03/31 12:52:01	1.3
  +++ Makefile.tmpl	1998/03/31 15:46:11	1.4
  @@ -94,6 +94,7 @@
   sysconfdir      = @sysconfdir@
   datadir         = @datadir@
   localstatedir   = @localstatedir@
  +includedir      = @includedir@
   
   libexecdir_relative   = @libexecdir_relative@
   localstatesubdir_run  = @localstatesubdir_run@
  @@ -157,6 +158,7 @@
   		install-programs \
   		install-support  \
   		install-config   \
  +		install-include  \
   		install-docroot 
   	-@rm -f .install.tmp
   	-@rm -f .install.conf
  @@ -189,6 +191,7 @@
   	@echo "===> [mktree: Creating Apache installation tree]"
   	$(MKDIR) $(bindir)
   	$(MKDIR) $(sbindir)
  +	$(MKDIR) $(libexecdir)
   	$(MKDIR) $(mandir)/man1
   	$(MKDIR) $(mandir)/man8
   	$(MKDIR) $(sysconfdir)
  @@ -198,6 +201,7 @@
   	$(MKDIR) $(localstatedir)/$(localstatesubdir_logs)
   	$(MKDIR) $(localstatedir)/$(localstatesubdir_run)
   	$(MKDIR) $(localstatedir)/proxy
  +	$(MKDIR) $(includedir)
   	@echo "<=== [mktree]"
   
   #   install the server program and optionally corresponding
  @@ -208,8 +212,6 @@
   	$(INSTALL_DATA) $(SRC)/support/httpd.8 $(mandir)/man8/httpd.8
   	-@rm -f .install.conf; touch .install.conf
   	-@if [ ".`grep '^[ 	]*SharedModule' $(SRC)/Configuration.apaci`" != . ]; then \
  -	    echo "$(MKDIR) $(libexecdir)"; \
  -	    $(MKDIR) $(libexecdir); \
           for mod in `egrep '^[ 	]*SharedModule' $(SRC)/Configuration.apaci |\
   	                sed -e 's/^[ 	]*SharedModule[ 	]*//'`; do \
   	        file=`echo $$mod | sed -e 's;^.*/\([^/]*\);\1;'`; \
  @@ -247,6 +249,15 @@
   	$(INSTALL_DATA) $(SRC)/support/logresolve.8 $(mandir)/man8/logresolve.8
   	$(INSTALL_PROGRAM) $(SRC)/support/rotatelogs $(sbindir)/rotatelogs
   	$(INSTALL_DATA) $(SRC)/support/rotatelogs.8 $(mandir)/man8/rotatelogs.8
  +	sed -e 's;^#!/.*;#!$(PERL);' \
  +		-e 's;\@prefix\@;$(prefix);' \
  +		-e 's;\@sbindir\@;$(sbindir);' \
  +		-e 's;\@libexecdir\@;$(libexecdir);' \
  +		-e 's;\@includedir\@;$(includedir);' \
  +		-e 's;\@sysconfdir\@;$(sysconfdir);' \
  +    	< $(SRC)/support/apxs > .install.tmp && \
  +    	$(INSTALL_SCRIPT) .install.tmp $(sbindir)/apxs
  +	$(INSTALL_DATA) $(SRC)/support/apxs.8 $(mandir)/man8/apxs.8
   	@if [ ".$(suexec)" = .1 ]; then \
   	    echo "$(INSTALL_PROGRAM) $(SRC)/support/suexec $(sbindir)/suexec"; \
   	    $(INSTALL_PROGRAM) $(SRC)/support/suexec $(sbindir)/suexec; \
  @@ -291,6 +302,14 @@
   	$(CP) $(ROOT)/conf/mime.types $(sysconfdir)/mime.types
   	$(CP) $(ROOT)/conf/magic $(sysconfdir)/magic
   	@echo "<=== [config]"
  +
  +#   install the Apache C header files 
  +install-include:
  +	@echo "===> [include: Installing Apache C header files]"
  +	$(CP) $(SRC)/include/*.h $(includedir)/
  +	osdir=`grep '^OSDIR' $(SRC)/Makefile.config | sed -e 's:^OSDIR=::'`; \
  +	$(CP) $(SRC)/$$osdir/os.h $(includedir)/
  +	@echo "<=== [include]"
   
   #   create an initial document root containing the Apache manual,
   #   icons and distributed CGI scripts.
  
  
  
  1.751     +16 -0     apache-1.3/src/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
  retrieving revision 1.750
  retrieving revision 1.751
  diff -u -r1.750 -r1.751
  --- CHANGES	1998/03/30 04:21:43	1.750
  +++ CHANGES	1998/03/31 15:46:14	1.751
  @@ -1,5 +1,21 @@
   Changes with Apache 1.3b6
   
  +  *) Add of the new APache eXtenSion (apxs) support tool for building and
  +     installing modules into an _already installed_ Apache package through the
  +     dynamic shared object (DSO) mechanism [mod_so.c]. The trick here is that
  +     this approach actually doesn't need the Apache source tree.  The
  +     (APACI-installed) server package is enough, because this now includes the
  +     Apache C header files (PREFIX/include) and the new APXS tool
  +     (SBINDIR/apxs).  The intend is to provide a handy tool for third-party
  +     module authors to build their Apache modules _OUTSIDE_ the Apache source
  +     tree while avoiding them to fiddle around with the totally platform
  +     dependend way of compiling DSO files. The tool supports all ranges of
  +     modules, from trivial ones (single mod_foo.c) to complex ones (like PHP3
  +     which has a mod_php3.c plus a pre-built libmodphp3-so.a) and even can
  +     on-the-fly generate a minimalistic Makefile and sample module for the
  +     first step to provide both a quick success event and to demonstrate the
  +     APXS mechanism to module authors. [Ralf S. Engelschall]
  +
     *) Fix core dumps in use of CONNECT in proxy.  PR#1326, #1573, #1942
        [Rainer.Scherg@rexroth.de]
   
  
  
  
  1.13      +9 -1      apache-1.3/src/support/Makefile.tmpl
  
  Index: Makefile.tmpl
  ===================================================================
  RCS file: /export/home/cvs/apache-1.3/src/support/Makefile.tmpl,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -r1.12 -r1.13
  --- Makefile.tmpl	1998/03/17 15:42:42	1.12
  +++ Makefile.tmpl	1998/03/31 15:46:16	1.13
  @@ -4,7 +4,7 @@
   INCLUDES=$(INCLUDES1) $(INCLUDES0) $(EXTRA_INCLUDES)
   LDFLAGS=$(LDFLAGS1) $(EXTRA_LDFLAGS) -L$(SRCDIR)/ap
   
  -TARGETS=htpasswd htdigest rotatelogs logresolve ab
  +TARGETS=htpasswd htdigest rotatelogs logresolve ab apxs
   
   OBJS=htpasswd.o htdigest.o rotatelogs.o logresolve.o ab.o
   
  @@ -27,6 +27,14 @@
   
   ab: ab.o
   	$(CC) $(INCLUDES) $(CFLAGS) ab.o -o ab $(LDFLAGS) $(LIBS)
  +
  +apxs: apxs.pl
  +	sed <apxs.pl >apxs \
  +	    -e 's:@CC@:$(CC):g' \
  +	    -e 's:@LD@:$(LD):g' \
  +	    -e 's:@CFLAGS@:$(CFLAGS):g' \
  +	    -e 's:@CFLAGS_SHLIB@:$(CFLAGS_SHLIB):g' \
  +	    -e 's:@LDFLAGS_SHLIB@:$(LDFLAGS_SHLIB):g' && chmod a+x apxs
   
   clean:
   	rm -f $(TARGETS) *.o
  
  
  
  1.1                  apache-1.3/src/support/apxs.8
  
  Index: apxs.8
  ===================================================================
  .TH apxs 8 "April 1998"
  .\" Copyright (c) 1998 The Apache Group. All rights reserved.
  .\"
  .\" Redistribution and use in source and binary forms, with or without
  .\" modification, are permitted provided that the following conditions
  .\" are met:
  .\"
  .\" 1. Redistributions of source code must retain the above copyright
  .\"    notice, this list of conditions and the following disclaimer. 
  .\"
  .\" 2. Redistributions in binary form must reproduce the above copyright
  .\"    notice, this list of conditions and the following disclaimer in
  .\"    the documentation and/or other materials provided with the
  .\"    distribution.
  .\"
  .\" 3. All advertising materials mentioning features or use of this
  .\"    software must display the following acknowledgment:
  .\"    "This product includes software developed by the Apache Group
  .\"    for use in the Apache HTTP server project (http://www.apache.org/)."
  .\"
  .\" 4. The names "Apache Server" and "Apache Group" must not be used to
  .\"    endorse or promote products derived from this software without
  .\"    prior written permission.
  .\"
  .\" 5. Products derived from this software may not be called "Apache"
  .\"    nor may "Apache" appear in their names without prior written
  .\"    permission of the Apache Group.
  .\"
  .\" 6. Redistributions of any form whatsoever must retain the following
  .\"    acknowledgment:
  .\"    "This product includes software developed by the Apache Group
  .\"    for use in the Apache HTTP server project (http://www.apache.org/)."
  .\"
  .\" THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  .\" EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  .\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  .\" ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  .\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  .\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  .\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  .\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  .\" OF THE POSSIBILITY OF SUCH DAMAGE.
  .\" ====================================================================
  .\"
  .\" This software consists of voluntary contributions made by many
  .\" individuals on behalf of the Apache Group and was originally based
  .\" on public domain software written at the National Center for
  .\" Supercomputing Applications, University of Illinois, Urbana-Champaign.
  .\" For more information on the Apache Group and the Apache HTTP server
  .\" project, please see <http://www.apache.org/>.
  .SH NAME
  apxs \- APache eXtenSion tool
  .SH SYNOPSIS
  .B apxs
  .B \-g
  .BI \-n " modname"
  
  .B apxs
  .B \-c
  [
  .BI \-o " dsofile"
  ]
  [
  .BI \-I " incdir"
  ]
  [
  .BI \-D " name=value"
  ]
  [
  .BI \-L " libdir"
  ]
  [
  .BI \-l " libname"
  ]
  .IR files " ..."
  
  .B apxs
  .B \-i
  [
  .BI \-n " modname"
  ]
  [
  .B \-a
  ]
  [
  .B \-A
  ]
  .IR dsofile " ..."
  .PP
  .SH DESCRIPTION
  .B apxs
  is a tool for building and installing extension modules for the Apache
  HyperText Transfer Protocol (HTTP) server. This is achieved by building a
  dynamic shared object (DSO) from one or more source or object
  .I files
  which then can be loaded into
  the Apache server under runtime via the
  .B LoadModule
  directive from
  .BR mod_so.
  
  So to use this extension mechanism your platform has
  to support the DSO feature and your
  Apache
  .B httpd
  binary has to be built with the
  .B mod_so
  module.
  The
  .B apxs
  tool automatically complains if this is not the case.
  You can check this yourself by manually running the command
  
  .nf
    $ httpd -l
  .fi
  
  The module
  .B mod_so
  should be part of the displayed list.
  If these requirements are fulfilled you can easily extend
  your Apache server's functionality by installing your own
  modules with the DSO mechanism by the help of this
  .B apxs
  tool:
  
  .nf
    $ apxs -i -a -c mod_foo.c
    gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    ld -Bshareable -o mod_foo.so mod_foo.o
    cp mod_foo.so /path/to/apache/libexec/mod_foo.so
    chmod 755 /path/to/apache/libexec/mod_foo.so
    [activating module `foo' in /path/to/apache/etc/httpd.conf]
    $ apachectl restart
    /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    /path/to/apache/sbin/apachectl restart: httpd started
    $ _
  .fi
  
  The arguments
  .I files
  can be any C source file (.c), a object file (.o) or
  even a library archive (.a). The
  .B apxs
  tool automatically recognizes these extensions and automtaically used the C
  source files for compilation while just using the object and archive files for
  the linking phase. But when using such pre-compiled objects make sure they are
  compiled for position independend code (PIC) to be able to use them for a
  dynamically loaded shared object.
  For instance with GCC you always just have to use
  .BR -fpic .
  For other
  C compilers consult its manual
  page or at watch for the flags
  .B apxs
  uses to compile the object files.
  
  For more details about DSO support in Apache read the documentation
  of
  .B mod_so
  or perhaps even read the
  .B src/modules/standard/mod_so.c
  source file.
  
  .PP
  .SH OPTIONS
  Shared options:
  .TP 12
  .BI \-n " modname"
  This explicitly sets the module name for the
  .B \-i
  (install)
  and
  .B \-g
  (template generation) option. Use this to explicitly specify the module name.
  For option
  .B \-g
  this is required, for option
  .B \-i
  the
  .B apxs
  tool tries to determine the name from the source or (as a fallback) at least
  by guessing it from the filename.
  .PP
  Template generation:
  .TP 12
  .B \-g
  This generates a subdirectory
  .I name
  (see option
  .BR \-n ")"
  and there two files: A sample module source file named
  .BI mod_ name.c
  which can be used as a template for creating your own modules or
  as a quick start for playing with the APXS mechanism.
  And a corresponding
  .B Makefile
  for even easier build and installing of this module.
  .PP
  Shared object compilation:
  .TP 12
  .B \-c
  This indicates the compilation operation. It first compiles the C source
  files (.c) of
  .I files
  into corresponding object files (.o) and then builds a dynamically shared object in
  .I dsofile
  by linking these object files plus the remaining
  object files (.o and .a) of
  .I files
  If no
  .B \-o
  option is specified
  the output file is guessed from the first filename in
  .I files
  and thus usually defaults to
  .BI mod_ name.so
  .TP 12
  .BI \-o " dsofile"
  Explicitly specifies the filename of the created dynamically shared object. If
  not specified and the name cannot be guessed from the
  .I files
  list, the fallback name
  .B mod_unknown.so
  is used.
  .TP 12
  .BI \-D " name=value"
  This option is directly passed through to the compilation command(s).
  Use this to add your own defines to the build process.
  .TP 12
  .BI \-I " incdir"
  This option is directly passed through to the compilation command(s).
  Use this to add your own include directories to search to the build process.
  .TP 12
  .BI \-L " libdir"
  This option is directly passed through to the linker command.
  Use this to add your own library directories to search to the build process.
  .TP 12
  .BI \-l " libname"
  This option is directly passed through to the linker command.
  Use this to add your own libraries to search to the build process.
  .PP
  Shared object installation:
  .TP 12
  .B \-i
  This indicates the installation operartion and installs one or more
  dynamically shared objects into the
  servers
  .I libexec
  directory.
  .TP 12
  .B \-a
  This additionally activates the module 
  by automatically adding a corresponding
  .B LoadModule
  line to Apache's
  .B httpd.conf
  configuration file (only if still no such entry exists).
  .TP 12
  .B \-A
  Same as option
  .B \-a
  but the created 
  .B LoadModule
  directive is
  prefixed with a hash sign (#), i.e. the module is
  just prepared for later activation but initially disabled. 
  .PD
  .SH EXAMPLES
  Assume you have an Apache module named mod_foo.c available which should extend
  Apache's server functionality. To accomplish this you first have to compile
  the C source into a shared object suitable for loading into the Apache server
  under runtime via the following command:
  
  .nf
    $ apxs -c mod_foo.c
    gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    ld -Bshareable -o mod_foo.so mod_foo.o
    $ _
  .fi
  
  Then you have to update the Apache configuration by making sure a
  .B LoadModule
  directive is present to load this shared object. To simplify this
  step
  .B apxs
  provides an automatic way to install the shared object in its
  "libexec" directory and updating the
  .B httpd.conf
  file accordingly. This can be achieved by running:
  
  .nf
    $ apxs -i -a mod_foo.c
    cp mod_foo.so /path/to/apache/libexec/mod_foo.so
    chmod 755 /path/to/apache/libexec/mod_foo.so
    [activating module `foo' in /path/to/apache/etc/httpd.conf]
    $ _
  .fi
  
  This way a line named
  
  .nf
    LoadModule foo_module libexec/mod_foo.so
  .fi
  
  is added to the configuration file if still not present.
  If you want to have this this disabled per default use the
  .B \-A
  option, i.e.
  
  .nf
    $ apxs -i -A mod_foo.c
  .fi
  
  For a quick test of the APXS mechanism you can create a sample Apache module
  template plus a corresponding Makefile via:
  
  .nf
    $ apxs -g -n foo
    Creating [DIR]  foo
    Creating [FILE] foo/Makefile
    Creating [FILE] foo/mod_foo.c
    $ _
  .fi
  
  Then you can immediately compile this sample module into a shared object and
  load it into the Apache server:
  
  .nf
    $ cd foo
    $ make all reload
    apxs -c mod_foo.c
    gcc -fpic -DSHARED_MODULE -I/path/to/apache/include -c mod_foo.c
    ld -Bshareable -o mod_foo.so mod_foo.o
    apxs -i -a -n "foo" mod_foo.so
    cp mod_foo.so /path/to/apache/libexec/mod_foo.so
    chmod 755 /path/to/apache/libexec/mod_foo.so
    [activating module `foo' in /path/to/apache/etc/httpd.conf]
    apachectl restart
    /path/to/apache/sbin/apachectl restart: httpd not running, trying to start
    [Tue Mar 31 11:27:55 1998] [debug] mod_so.c(303): loaded module foo_module
    /path/to/apache/sbin/apachectl restart: httpd started
    $ _
  .fi
  
  You can even use
  .B apxs
  to compile complex modules outside the Apache source tree, like PHP3:
  
  .nf
    $ cd php3
    $ ./configure --with-shared-apache=../apache-1.3
    $ apxs -c -o libphp3.so mod_php3.c libmodphp3-so.a
    gcc -fpic -DSHARED_MODULE -I/tmp/apache/include  -c mod_php3.c
    ld -Bshareable -o libphp3.so mod_php3.o libmodphp3-so.a
    $ _
  .fi
  
  because
  .B apxs
  automatically recognized C source files and object files.  Only C source files
  are compiled while remaining object files are used for the linking phase.
  
  .PD
  .SH SEE ALSO
  .BR apachectl(1),
  .BR httpd(8).
  .
  
  
  
  1.1                  apache-1.3/src/support/apxs.pl
  
  Index: apxs.pl
  ===================================================================
  #!/usr/local/bin/perl
  ## ====================================================================
  ## Copyright (c) 1998 The Apache Group.  All rights reserved.
  ##
  ## Redistribution and use in source and binary forms, with or without
  ## modification, are permitted provided that the following conditions
  ## are met:
  ##
  ## 1. Redistributions of source code must retain the above copyright
  ##    notice, this list of conditions and the following disclaimer. 
  ##
  ## 2. Redistributions in binary form must reproduce the above copyright
  ##    notice, this list of conditions and the following disclaimer in
  ##    the documentation and/or other materials provided with the
  ##    distribution.
  ##
  ## 3. All advertising materials mentioning features or use of this
  ##    software must display the following acknowledgment:
  ##    "This product includes software developed by the Apache Group
  ##    for use in the Apache HTTP server project (http://www.apache.org/)."
  ##
  ## 4. The names "Apache Server" and "Apache Group" must not be used to
  ##    endorse or promote products derived from this software without
  ##    prior written permission. For written permission, please contact
  ##    apache@apache.org.
  ##
  ## 5. Products derived from this software may not be called "Apache"
  ##    nor may "Apache" appear in their names without prior written
  ##    permission of the Apache Group.
  ##
  ## 6. Redistributions of any form whatsoever must retain the following
  ##    acknowledgment:
  ##    "This product includes software developed by the Apache Group
  ##    for use in the Apache HTTP server project (http://www.apache.org/)."
  ##
  ## THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  ## EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  ## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  ## PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  ## ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  ## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  ## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  ## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  ## STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  ## ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  ## OF THE POSSIBILITY OF SUCH DAMAGE.
  ## ====================================================================
  ##
  ## This software consists of voluntary contributions made by many
  ## individuals on behalf of the Apache Group and was originally based
  ## on public domain software written at the National Center for
  ## Supercomputing Applications, University of Illinois, Urbana-Champaign.
  ## For more information on the Apache Group and the Apache HTTP server
  ## project, please see <http://www.apache.org/>.
  ##
  
  ##
  ##  apxs -- APache eXtenSion tool
  ##  Written by Ralf S. Engelschall <rs...@apache.org>
  ##
  
  require 5.004;
  use strict;
  package apxs;
  
  ##
  ##  Configuration
  ##
  
  my $CFG_CC            = '@CC@';            # substituted via Makefile.tmpl
  my $CFG_LD            = '@LD@';            # substituted via Makefile.tmpl
  my $CFG_CFLAGS        = '@CFLAGS@';        # substituted via Makefile.tmpl
  my $CFG_CFLAGS_SHLIB  = '@CFLAGS_SHLIB@';  # substituted via Makefile.tmpl
  my $CFG_LDFLAGS_SHLIB = '@LDFLAGS_SHLIB@'; # substituted via Makefile.tmpl 
  my $CFG_PREFIX        = '@prefix@';        # substituted via APACI install
  my $CFG_SBINDIR       = '@sbindir@';       # substituted via APACI install
  my $CFG_INCDIR        = '@includedir@';    # substituted via APACI install
  my $CFG_LIBEXECDIR    = '@libexecdir@';    # substituted via APACI install
  my $CFG_SYSCONFDIR    = '@sysconfdir@';    # substituted via APACI install
  
  ##
  ##  Initial shared object support check
  ##
  if (not grep(/mod_so/, `$CFG_SBINDIR/httpd -l`)) {
      print STDERR "apxs:Error: Sorry, no shared object support for Apache\n";
      print STDERR "apxs:Error: available under your platform. Make sure\n";
      print STDERR "apxs:Error: the Apache module mod_so is compiled into\n";
      print STDERR "apxs:Error: your server binary `$CFG_SBINDIR/httpd'.\n";
      exit(1);
  }
  
  ##
  ##  parse argument line
  ##
  
  #   defaults for parameters
  my $opt_n = '';
  my $opt_g = '';
  my $opt_c = 0;
  my $opt_o = '';
  my @opt_D = ();
  my @opt_I = ();
  my @opt_L = ();
  my @opt_l = ();
  my $opt_i = 0;
  my $opt_a = 0;
  my $opt_A = 0;
  
  #   this subroutine is derived from Perl's getopts.pl with the enhancement of
  #   the "+" metacharater at the format string to allow a list to be build by
  #   subsequent occurance of the same option.
  sub Getopts {
      my ($argumentative, @ARGV) = @_;
      my (@args, $first, $rest, $pos);
      my ($errs) = 0;
      local ($_);
      local ($[) = 0;
  
      @args = split( / */, $argumentative);
      while(@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) {
          ($first, $rest) = ($1,$2);
          if ($_ =~ m|^--$|) {
              shift(@ARGV);
              last;
          }
          $pos = index($argumentative,$first);
          if($pos >= $[) {
              if($args[$pos+1] eq ':') {
                  shift(@ARGV);
                  if($rest eq '') {
                      unless (@ARGV) {
                          print STDERR "apxs:Error: Incomplete option: $first (needs an argument)\n";
                          ++$errs;
                      }
                      $rest = shift(@ARGV);
                  }
                  eval "\$opt_$first = \$rest;";
              }
              elsif ($args[$pos+1] eq '+') {
                  shift(@ARGV);
                  if($rest eq '') {
                      unless (@ARGV) {
                          print STDERR "apxs:Error: Incomplete option: $first (needs an argument)\n";
                          ++$errs;
                      }
                      $rest = shift(@ARGV);
                  }
                  eval "push(\@opt_$first, \$rest);";
              }
              else {
                  eval "\$opt_$first = 1";
                  if($rest eq '') {
                      shift(@ARGV);
                  }
                  else {
                      $ARGV[0] = "-$rest";
                  }
              }
          }
          else {
              print STDERR "apxs:Error: Unknown option: $first\n";
              ++$errs;
              if($rest ne '') {
                  $ARGV[0] = "-$rest";
              }
              else {
                  shift(@ARGV);
              }
          }
      }
      return ($errs == 0, @ARGV);
  }
  
  sub usage {
      print STDERR "apxs:Usage: apxs -g -n <name>\n";
      print STDERR "apxs:Usage: apxs -c [-o mod_<name>.so] [-D..] [-I..] [-l..] [-L..] mod_<name>.c ...\n";
      print STDERR "apxs:Usage: apxs -i [-e] [-n <name>] mod_<name>.so ...\n";
      exit(1);
  }
  
  #   option handling
  my $rc;
  ($rc, @ARGV) = &Getopts("n:gco:I+D+L+l+iaA", @ARGV);
  &usage if ($rc == 0);
  &usage if ($#ARGV == -1 and not $opt_g);
  &usage if (not ($opt_g and $opt_n) and not $opt_i and not $opt_c);
  
  #   argument handling
  my @files = @ARGV;
  my $name = 'unknown';
  $name = $opt_n if ($opt_n ne '');
  
  ##
  ##  Operation
  ##
  
  #   helper function for executing a list of
  #   system command with return code checks
  sub execute_cmds {
      my (@cmds) = @_;
      my ($cmd, $rc);
  
      foreach $cmd (@cmds) {
          print STDERR "$cmd\n";
          $rc = system("$cmd");
          if ($rc != 0) {
              printf(STDERR "apxs:Break: Command failed with rc=%d\n", $rc << 8);
              exit(1);
          }
      }
  }
  
  if ($opt_g) {
      ##
      ##  SAMPLE MODULE SOURCE GENERATION
      ##
  
      if (-d $name) {
          print STDERR "apxs:Error: Directory `$name' already exists. Remove first\n";
          exit(1);
      }
  
      my $data = join('', <DATA>);
      $data =~ s|%NAME%|$name|sg;
  
      my ($mkf, $src) = ($data =~ m|^(.+)-=#=-\n(.+)|s);
  
      print STDERR "Creating [DIR]  $name\n";
      system("mkdir $name");
      print STDERR "Creating [FILE] $name/Makefile\n";
      open(FP, ">${name}/Makefile") || die;
      print FP $mkf;
      close(FP);
      print STDERR "Creating [FILE] $name/mod_$name.c\n";
      open(FP, ">${name}/mod_${name}.c") || die;
      print FP $src;
      close(FP);
  
      exit(0);
  }
  
  if ($opt_c) {
      ##
      ##  SHARED OBJECT COMPILATION
      ##
  
      #   split files into sources and objects
      my @srcs = ();
      my @objs = ();
      my $f;
      foreach $f (@files) {
          if ($f =~ m|\.c$|) {
              push(@srcs, $f);
          }
          else {
              push(@objs, $f);
          }
      }
  
      #   determine output file
      my $dso_file;
      if ($opt_o eq '') {
          if ($#srcs > -1) {
              $dso_file = $srcs[0];
              $dso_file =~ s|\.[^.]+$|.so|;
          }
          elsif ($#objs > -1) {
              $dso_file = $objs[0];
              $dso_file =~ s|\.[^.]+$|.so|;
          }
          else {
              $dso_file = "mod_unknown.so";
          }
      }
      else {
          $dso_file = $opt_o;
      }
  
      #   create compilation commands
      my @cmds = ();
      my $opt = '';
      my ($opt_I, $opt_D);
      foreach $opt_I (@opt_I) {
          $opt .= "-I$opt_I ";
      }
      foreach $opt_D (@opt_D) {
          $opt .= "-D$opt_D ";
      }
      my $cflags = "$CFG_CFLAGS $CFG_CFLAGS_SHLIB";
      $cflags =~ s|^\s+||;
      $cflags =~ s|\s+$||;
      $cflags =~ s|\s+`.+apaci`||;
      my $s;
      foreach $s (@srcs) {
          my $o = $s;
          $o =~ s|\.c$|.o|;
          push(@cmds, "$CFG_CC $cflags -I$CFG_INCDIR $opt -c $s");
          unshift(@objs, $o);
      }
  
      #   create link command
      my $cmd = "$CFG_LD $CFG_LDFLAGS_SHLIB -o $dso_file";
      my $o;
      foreach $o (@objs) {
          $cmd .= " $o";
      }
      $opt = '';
      my ($opt_L, $opt_l);
      foreach $opt_L (@opt_L) {
          $opt .= " -L$opt_L";
      }
      foreach $opt_l (@opt_l) {
          $opt .= " -l$opt_l";
      }
      $cmd .= $opt;
      push(@cmds, $cmd);
  
      #   execute the commands
      &execute_cmds(@cmds);
  
      #   allow one-step compilation and installation
      if ($opt_i) {
          @files = ( $dso_file );
      }
  }
  
  if ($opt_i) {
      ##
      ##  SHARED OBJECT INSTALLATION
      ##
  
      #   determine installation commands
      #   and corresponding LoadModule directives
      my @lmd = ();
      my @cmds = ();
      my $f;
      foreach $f (@files) {
          if ($f !~ m|\.so$|) {
              print STDERR "apxs:Error: file $f is not a shared object\n";
              exit(1);
          }
          my $t = $f;
          $t =~ s|^.+/([^/]+)$|$1|;
          push(@cmds, "cp $f $CFG_LIBEXECDIR/$t");
          push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t");
  
          #   determine module name
          if ($name eq 'unknown') {
              $name = '';
              my $base = $f;
              $base =~ s|\.[^.]+$||;
              if (-f "$base.c") {
                  open(FP, "<$base.c");
                  my $content = join('', <FP>);
                  close(FP);
                  if ($content =~ m|.*module\s+(?:MODULE_VAR_EXPORT\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) {
                      $name = "$1";
                  }
              }
              if ($name eq '') {
                  if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) {
                      $name = "$1";
                  }
              }
              if ($name eq '') {
                  print "apxs:Error: Sorry, cannot determine bootstrap symbol name\n";
                  print "apxs:Error: Please specify one with option `-n'\n";
                  exit(1);
              }
          }
          my $dir = $CFG_LIBEXECDIR;
          $dir =~ s|^$CFG_PREFIX/?||;
          $dir =~ s|(.)$|$1/|;
          push(@lmd, "LoadModule ${name}_module $dir$t");
      }
  
      #   execute the commands
      &execute_cmds(@cmds);
  
      #   activate module via LoadModule directive
      if ($opt_a or $opt_A) {
          if (not -f "$CFG_SYSCONFDIR/httpd.conf") {
              print "apxs:Error: Config file $CFG_SYSCONFDIR/httpd.conf not found\n";
              exit(1);
          }
  
          open(FP, "<$CFG_SYSCONFDIR/httpd.conf") || die;
          my $content = join('', <FP>);
          close(FP);
  
          if ($content !~ m|\n#?\s*LoadModule\s+|) {
              print STDERR "apxs:Error: Activation failed for custom $CFG_SYSCONFDIR/httpd.conf file.\n";
              print STDERR "apxs:Error: At least one `LoadModule' directive already has to exist.\n";
              exit(1);
          }
  
          my $update = 0;
          my $lmd;
          foreach $lmd (@lmd) {
              if ($content !~ m|\n#?\s*$lmd|) {
                   my $c = '';
                   $c = '#' if ($opt_A);
                   $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|sg;
                   $update = 1;
                   $lmd =~ m|LoadModule\s+(.+?)_module.*|;
                   my $what = $opt_A ? "preparing" : "activating";
                   print STDERR "[$what module `$1' in $CFG_SYSCONFDIR/httpd.conf]\n";
              }
          }
          if ($update) {
              open(FP, ">$CFG_SYSCONFDIR/httpd.conf.new") || die;
              print FP $content;
              close(FP);
              system("cp $CFG_SYSCONFDIR/httpd.conf $CFG_SYSCONFDIR/httpd.conf.bak && " .
                     "cp $CFG_SYSCONFDIR/httpd.conf.new $CFG_SYSCONFDIR/httpd.conf && " .
                     "rm $CFG_SYSCONFDIR/httpd.conf.new");
          }
      }
  }
  
  ##EOF##
  __DATA__
  ##
  ##  Makefile -- Apache for sample %NAME% module
  ##  Autogenerated via ``apxs -n %NAME% -g''.
  ##
  
  #   additional defines and includes
  #DEF=-Dmy_define=my_value
  #INC=-Imy/include/dir
  
  #   the default target
  all: mod_%NAME%.so
  
  #   compile the shared object file
  mod_%NAME%.so: mod_%NAME%.c
  	apxs -c $(DEF) $(INC) mod_%NAME%.c
  
  #   install the shared object file into Apache 
  install: all
  	apxs -i -a -n '%NAME%' mod_%NAME%.so
  
  #   cleanup
  clean:
  	-rm -f mod_%NAME%.o mod_%NAME%.so
  
  #   install and activate shared object by reloading Apache to
  #   force a reload of the shared object file
  reload: install restart
  
  #   the general Apache start/restart/top #   procedures
  start:
  	apachectl start
  restart:
  	apachectl restart
  stop:
  	apachectl stop
  
  -=#=-
  /* 
  **  mod_%NAME%.c -- Apache sample %NAME% module
  **  [Autogenerated via ``apxs -n %NAME% -g'']
  **
  **  To play with this sample module first compile it into a
  **  DSO file and install it into Apache's libexec directory 
  **  by running:
  **
  **    $ apxs -c -i mod_%NAME%.c
  **
  **  Then activate it in Apache's httpd.conf file for instance
  **  for the URL /%NAME% in as follows:
  **
  **    #   httpd.conf
  **    LoadModule %NAME%_module libexec/mod_%NAME%.so
  **    <Location /%NAME%>
  **    SetHandler %NAME%
  **    </Location>
  **
  **  Then after restarting Apache via
  **
  **    $ apachectl restart
  **
  **  you immediately can request the URL /%NAME and watch for the
  **  output of this module. This can be achieved for instance via:
  **
  **    $ lynx -mime_header http://localhost/%NAME% 
  **
  **  The output should be similar to the following one:
  **
  **    HTTP/1.1 200 OK
  **    Date: Tue, 31 Mar 1998 14:42:22 GMT
  **    Server: Apache/1.3b6-dev
  **    Connection: close
  **    Content-Type: text/html
  **  
  **    The sample page from mod_%NAME%.c
  */ 
  
  #include "httpd.h"
  #include "http_config.h"
  #include "conf.h"
  
  /* The sample content handler */
  static int %NAME%_handler(request_rec *r)
  {
      r->content_type = "text/html";      
      send_http_header(r);
      if (!r->header_only)
          rputs("The sample page from mod_%NAME%.c\n", r);
      return OK;
  }
  
  /* Dispatch list of content handlers */
  static const handler_rec %NAME%_handlers[] = { 
      { "%NAME%", %NAME%_handler }, 
      { NULL, NULL }
  };
  
  /* Dispatch list for API hooks */
  module MODULE_VAR_EXPORT %NAME%_module = {
      STANDARD_MODULE_STUFF, 
      NULL,                  /* module initializer                  */
      NULL,                  /* create per-dir    config structures */
      NULL,                  /* merge  per-dir    config structures */
      NULL,                  /* create per-server config structures */
      NULL,                  /* merge  per-server config structures */
      NULL,                  /* table of config file commands       */
      %NAME%_handlers,       /* [#8] MIME-typed-dispatched handlers */
      NULL,                  /* [#1] URI to filename translation    */
      NULL,                  /* [#4] validate user id from request  */
      NULL,                  /* [#5] check if the user is ok _here_ */
      NULL,                  /* [#2] check access by host address   */
      NULL,                  /* [#6] determine MIME type            */
      NULL,                  /* [#7] pre-run fixups                 */
      NULL,                  /* [#9] log a transaction              */
      NULL,                  /* [#3] header parser                  */
      NULL,                  /* child_init                          */
      NULL,                  /* child_exit                          */
      NULL                   /* [#0] post read-request              */
  };