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 */
};