| #!@perlbin@ -w |
| # ==================================================================== |
| # The Apache Software License, Version 1.1 |
| # |
| # Copyright (c) 2000-2002 The Apache Software Foundation. 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. The end-user documentation included with the redistribution, |
| # if any, must include the following acknowledgment: |
| # "This product includes software developed by the |
| # Apache Software Foundation (http://www.apache.org/)." |
| # Alternately, this acknowledgment may appear in the software itself, |
| # if and wherever such third-party acknowledgments normally appear. |
| # |
| # 4. The names "Apache" and "Apache Software Foundation" 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 name, without prior written |
| # permission of the Apache Software Foundation. |
| # |
| # THIS SOFTWARE IS PROVIDED ``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 SOFTWARE FOUNDATION 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 Software Foundation. For more |
| # information on the Apache Software Foundation, please see |
| # <http://www.apache.org/>. |
| # |
| |
| require 5.003; |
| use strict; |
| package apxs; |
| |
| ## |
| ## Configuration |
| ## |
| |
| my $prefix = "@prefix@"; |
| my $CFG_PREFIX = $prefix; |
| |
| # read the configuration variables once |
| my %config_vars = (); |
| get_config_vars("$prefix/build/config_vars.mk",\%config_vars); |
| |
| my $exec_prefix = get_vars("exec_prefix"); |
| my $CFG_TARGET = get_vars("progname"); |
| my $CFG_SYSCONFDIR = get_vars("sysconfdir"); |
| my $CFG_CFLAGS = join ' ', map { get_vars($_) } |
| qw(SHLTCFLAGS CFLAGS NOTEST_CPPFLAGS EXTRA_CPPFLAGS EXTRA_CFLAGS); |
| my $includedir = get_vars("includedir"); |
| my $CFG_INCLUDEDIR = eval qq("$includedir"); |
| my $CFG_CC = get_vars("CC"); |
| my $libexecdir = get_vars("libexecdir"); |
| my $CFG_LIBEXECDIR = eval qq("$libexecdir"); |
| my $sbindir = get_vars("sbindir"); |
| my $CFG_SBINDIR = eval qq("$sbindir"); |
| my $ltflags = $ENV{'LTFLAGS'}; |
| $ltflags or $ltflags = "--silent"; |
| |
| my %internal_vars = map {$_ => 1} |
| qw(TARGET CC CFLAGS CFLAGS_SHLIB LD_SHLIB LDFLAGS_SHLIB LIBS_SHLIB |
| PREFIX SBINDIR INCLUDEDIR LIBEXECDIR SYSCONFDIR); |
| |
| ## |
| ## 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_W = (); |
| my @opt_S = (); |
| my $opt_e = 0; |
| my $opt_i = 0; |
| my $opt_a = 0; |
| my $opt_A = 0; |
| my $opt_q = 0; |
| my $opt_h = 0; |
| |
| # this subroutine is derived from Perl's getopts.pl with the enhancement of |
| # the "+" metacharacter at the format string to allow a list to be built by |
| # subsequent occurrences of the same option. |
| sub Getopts { |
| my ($argumentative, @ARGV) = @_; |
| my $errs = 0; |
| local $_; |
| local $[ = 0; |
| |
| my @args = split / */, $argumentative; |
| while (@ARGV && ($_ = $ARGV[0]) =~ /^-(.)(.*)/) { |
| my ($first, $rest) = ($1,$2); |
| if ($_ =~ m|^--$|) { |
| shift @ARGV; |
| last; |
| } |
| my $pos = index($argumentative,$first); |
| if ($pos >= $[) { |
| if ($args[$pos+1] eq ':') { |
| shift @ARGV; |
| if ($rest eq '') { |
| unless (@ARGV) { |
| error("Incomplete option: $first (needs an argument)"); |
| $errs++; |
| } |
| $rest = shift(@ARGV); |
| } |
| eval "\$opt_$first = \$rest;"; |
| } |
| elsif ($args[$pos+1] eq '+') { |
| shift @ARGV; |
| if ($rest eq '') { |
| unless (@ARGV) { |
| error("Incomplete option: $first (needs an argument)"); |
| $errs++; |
| } |
| $rest = shift(@ARGV); |
| } |
| eval "push(\@opt_$first, \$rest);"; |
| } |
| else { |
| eval "\$opt_$first = 1"; |
| if ($rest eq '') { |
| shift(@ARGV); |
| } |
| else { |
| $ARGV[0] = "-$rest"; |
| } |
| } |
| } |
| else { |
| error("Unknown option: $first"); |
| $errs++; |
| if ($rest ne '') { |
| $ARGV[0] = "-$rest"; |
| } |
| else { |
| shift(@ARGV); |
| } |
| } |
| } |
| return ($errs == 0, @ARGV); |
| } |
| |
| sub usage { |
| print STDERR "Usage: apxs -g [-S <var>=<val>] -n <modname>\n"; |
| print STDERR " apxs -q [-S <var>=<val>] <query> ...\n"; |
| print STDERR " apxs -c [-S <var>=<val>] [-o <dsofile>] [-D <name>[=<value>]]\n"; |
| print STDERR " [-I <incdir>] [-L <libdir>] [-l <libname>] [-Wc,<flags>]\n"; |
| print STDERR " [-Wl,<flags>] <files> ...\n"; |
| print STDERR " apxs -i [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n"; |
| print STDERR " apxs -e [-S <var>=<val>] [-a] [-A] [-n <modname>] <dsofile> ...\n"; |
| exit(1); |
| } |
| |
| # option handling |
| my $rc; |
| ($rc, @ARGV) = &Getopts("qn:gco:I+D+L+l+W+S+eiaA", @ARGV); |
| &usage if ($rc == 0); |
| &usage if ($#ARGV == -1 and not $opt_g); |
| &usage if (not $opt_q and not ($opt_g and $opt_n) and not $opt_i and not $opt_c and not $opt_e); |
| |
| # argument handling |
| my @args = @ARGV; |
| my $name = 'unknown'; |
| $name = $opt_n if ($opt_n ne ''); |
| |
| if (@opt_S) { |
| my ($opt_S); |
| foreach $opt_S (@opt_S) { |
| if ($opt_S =~ m/^([^=]+)=(.*)$/) { |
| my ($var) = $1; |
| my ($val) = $2; |
| my $oldval = eval "\$CFG_$var"; |
| |
| unless ($var and $oldval) { |
| print STDERR "apxs:Error: no config variable $var\n"; |
| &usage; |
| } |
| |
| eval "\$CFG_${var}=\"${val}\""; |
| } else { |
| print STDERR "apxs:Error: malformatted -S option\n"; |
| &usage; |
| } |
| } |
| } |
| |
| ## |
| ## Initial shared object support check |
| ## |
| my $httpd = get_vars("sbindir") . "/" . get_vars("progname"); |
| $httpd = eval qq("$httpd"); |
| $httpd = eval qq("$httpd"); |
| |
| #allow apxs to be run from the source tree, before installation |
| if ($0 =~ m:support/apxs$:) { |
| ($httpd = $0) =~ s:support/apxs$::; |
| } |
| |
| unless (-x "$httpd") { |
| error("$httpd not found or not executable"); |
| exit 1; |
| } |
| |
| unless (grep /mod_so/, `$httpd -l`) { |
| error("Sorry, no shared object support for Apache"); |
| error("available under your platform. Make sure"); |
| error("the Apache module mod_so is compiled into"); |
| error("your server binary `$httpd'."); |
| exit 1; |
| } |
| |
| sub get_config_vars{ |
| my ($file, $rh_config) = @_; |
| |
| open IN, $file or die "cannot open $file: $!"; |
| while (<IN>){ |
| if (/^\s*(.*?)\s*=\s*(.*)$/){ |
| $rh_config->{$1} = $2; |
| } |
| } |
| close IN; |
| } |
| |
| sub get_vars { |
| my $result = ''; |
| my $ok = 0; |
| my $arg; |
| foreach $arg (@_) { |
| if (exists $config_vars{$arg} or exists $config_vars{lc $arg}) { |
| my $val = exists $config_vars{$arg} |
| ? $config_vars{$arg} |
| : $config_vars{lc $arg}; |
| $val =~ s/[()]//g; |
| $result .= eval "qq($val)"; |
| $result .= ";;"; |
| $ok = 1; |
| } |
| if (not $ok) { |
| if (exists $internal_vars{$arg} or exists $internal_vars{lc $arg}) { |
| my $val = exists $internal_vars{$arg} ? $arg : lc $arg; |
| $val = eval "\$CFG_$val"; |
| $result .= eval "qq($val)"; |
| $result .= ";;"; |
| $ok = 1; |
| } |
| if (not $ok) { |
| error("Invalid query string `$arg'"); |
| exit(1); |
| } |
| } |
| } |
| $result =~ s|;;$||; |
| $result =~ s|:| |; |
| return $result; |
| } |
| |
| ## |
| ## 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) { |
| notice($cmd); |
| $rc = system $cmd; |
| if ($rc) { |
| error(sprintf "Command failed with rc=%d\n", $rc << 8); |
| exit 1 ; |
| } |
| } |
| } |
| |
| if ($opt_g) { |
| ## |
| ## SAMPLE MODULE SOURCE GENERATION |
| ## |
| |
| if (-d $name) { |
| error("Directory `$name' already exists. Remove first"); |
| exit(1); |
| } |
| |
| my $data = join('', <DATA>); |
| $data =~ s|%NAME%|$name|sg; |
| $data =~ s|%TARGET%|$CFG_TARGET|sg; |
| $data =~ s|%PREFIX%|$prefix|sg; |
| |
| my ($mkf, $mods, $src) = ($data =~ m|^(.+)-=#=-\n(.+)-=#=-\n(.+)|s); |
| |
| notice("Creating [DIR] $name"); |
| system("mkdir $name"); |
| notice("Creating [FILE] $name/Makefile"); |
| open(FP, ">${name}/Makefile") || die; |
| print FP $mkf; |
| close(FP); |
| notice("Creating [FILE] $name/modules.mk"); |
| open(FP, ">${name}/modules.mk") || die; |
| print FP $mods; |
| close(FP); |
| notice("Creating [FILE] $name/mod_$name.c"); |
| open(FP, ">${name}/mod_${name}.c") || die; |
| print FP $src; |
| close(FP); |
| notice("Creating [FILE] $name/.deps"); |
| system("touch ${name}/.deps"); |
| |
| exit(0); |
| } |
| |
| |
| if ($opt_q) { |
| ## |
| ## QUERY INFORMATION |
| ## |
| my $result = get_vars(@args); |
| print "$result"; |
| } |
| |
| if ($opt_c) { |
| ## |
| ## SHARED OBJECT COMPILATION |
| ## |
| |
| # split files into sources and objects |
| my @srcs = (); |
| my @objs = (); |
| my $f; |
| foreach $f (@args) { |
| 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|\.[^.]+$|.la|; |
| } |
| elsif ($#objs > -1) { |
| $dso_file = $objs[0]; |
| $dso_file =~ s|\.[^.]+$|.la|; |
| } |
| else { |
| $dso_file = "mod_unknown.so"; |
| } |
| } |
| else { |
| $dso_file = $opt_o; |
| } |
| |
| # create compilation commands |
| my @cmds = (); |
| my $opt = ''; |
| my ($opt_Wc, $opt_I, $opt_D); |
| foreach $opt_Wc (@opt_W) { |
| $opt .= "$1 " if ($opt_Wc =~ m|^\s*c,(.*)$|); |
| } |
| foreach $opt_I (@opt_I) { |
| $opt .= "-I$opt_I "; |
| } |
| foreach $opt_D (@opt_D) { |
| $opt .= "-D$opt_D "; |
| } |
| my $cflags = "$CFG_CFLAGS"; |
| my $s; |
| my $mod; |
| foreach $s (@srcs) { |
| my $slo = $s; |
| $slo =~ s|\.c$|.slo|; |
| my $lo = $s; |
| $lo =~ s|\.c$|.lo|; |
| my $la = $s; |
| $la =~ s|\.c$|.la|; |
| my $o = $s; |
| $o =~ s|\.c$|.o|; |
| push(@cmds, "$prefix/build/libtool $ltflags --mode=compile $CFG_CC $cflags -I$CFG_INCLUDEDIR $opt -c -o $lo $s && touch $slo"); |
| unshift(@objs, $lo); |
| } |
| |
| # create link command |
| my $o; |
| my $lo; |
| foreach $o (@objs) { |
| $lo .= " $o"; |
| } |
| my ($opt_Wl, $opt_L, $opt_l); |
| foreach $opt_Wl (@opt_W) { |
| if ($CFG_CC !~ m/gcc$/) { |
| $opt .= " $1" if ($opt_Wl =~ m|^\s*l,(.*)$|); |
| } else { |
| $opt .= " -W$opt_Wl"; |
| } |
| } |
| foreach $opt_L (@opt_L) { |
| $opt .= " -L$opt_L"; |
| } |
| foreach $opt_l (@opt_l) { |
| $opt .= " -l$opt_l"; |
| } |
| |
| push(@cmds, "$prefix/build/libtool $ltflags --mode=link $CFG_CC -o $dso_file -rpath $CFG_LIBEXECDIR -module -avoid-version $opt $lo"); |
| |
| # execute the commands |
| &execute_cmds(@cmds); |
| |
| # allow one-step compilation and installation |
| if ($opt_i or $opt_e) { |
| @args = ( $dso_file ); |
| } |
| } |
| |
| if ($opt_i or $opt_e) { |
| ## |
| ## SHARED OBJECT INSTALLATION |
| ## |
| |
| # determine installation commands |
| # and corresponding LoadModule/AddModule directives |
| my @lmd = (); |
| my @amd = (); |
| my @cmds = (); |
| my $f; |
| foreach $f (@args) { |
| if ($f !~ m#(\.so$|\.la$)#) { |
| error("file $f is not a shared object"); |
| exit(1); |
| } |
| my $t = $f; |
| $t =~ s|^.+/([^/]+)$|$1|; |
| $t =~ s|\.la$|\.so|; |
| if ($opt_i) { |
| push(@cmds, "$prefix/build/instdso.sh SH_LIBTOOL='" . |
| "$prefix/build/libtool' $f $CFG_LIBEXECDIR"); |
| push(@cmds, "chmod 755 $CFG_LIBEXECDIR/$t"); |
| } |
| |
| # determine module symbolname and filename |
| my $filename = ''; |
| 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+(?:AP_MODULE_DECLARE_DATA\s+)?([a-zA-Z0-9_]+)_module\s*=\s*.*|s) { |
| $name = "$1"; |
| $filename = "$base.c"; |
| $filename =~ s|^[^/]+/||; |
| } |
| } |
| if ($name eq '') { |
| if ($base =~ m|.*mod_([a-zA-Z0-9_]+)\..+|) { |
| $name = "$1"; |
| $filename = $base; |
| $filename =~ s|^[^/]+/||; |
| } |
| } |
| if ($name eq '') { |
| error("Sorry, cannot determine bootstrap symbol name"); |
| error("Please specify one with option `-n'"); |
| exit(1); |
| } |
| } |
| if ($filename eq '') { |
| $filename = "mod_${name}.c"; |
| } |
| my $dir = $CFG_LIBEXECDIR; |
| $dir =~ s|^$CFG_PREFIX/?||; |
| $dir =~ s|(.)$|$1/|; |
| $t =~ s|\.la$|.so|; |
| push(@lmd, sprintf("LoadModule %-18s %s", "${name}_module", "$dir$t")); |
| push(@amd, sprintf("AddModule %s", $filename)); |
| } |
| |
| # execute the commands |
| &execute_cmds(@cmds); |
| |
| # activate module via LoadModule/AddModule directive |
| if ($opt_a or $opt_A) { |
| if (not -f "$CFG_SYSCONFDIR/$CFG_TARGET.conf") { |
| error("Config file $CFG_SYSCONFDIR/$CFG_TARGET.conf not found"); |
| exit(1); |
| } |
| |
| open(FP, "<$CFG_SYSCONFDIR/$CFG_TARGET.conf") || die; |
| my $content = join('', <FP>); |
| close(FP); |
| |
| if ($content !~ m|\n#?\s*LoadModule\s+|) { |
| error("Activation failed for custom $CFG_SYSCONFDIR/$CFG_TARGET.conf file."); |
| error("At least one `LoadModule' directive already has to exist."); |
| exit(1); |
| } |
| |
| my $lmd; |
| my $c = ''; |
| $c = '#' if ($opt_A); |
| foreach $lmd (@lmd) { |
| my $what = $opt_A ? "preparing" : "activating"; |
| if ($content !~ m|\n#?\s*$lmd|) { |
| $content =~ s|^(.*\n#?\s*LoadModule\s+[^\n]+\n)|$1$c$lmd\n|sg; |
| } else { |
| $content =~ s|^(.*\n)#?\s*$lmd[^\n]*\n|$1$c$lmd\n|sg; |
| } |
| $lmd =~ m|LoadModule\s+(.+?)_module.*|; |
| notice("[$what module `$1' in $CFG_SYSCONFDIR/$CFG_TARGET.conf]"); |
| } |
| my $amd; |
| foreach $amd (@amd) { |
| if ($content !~ m|\n#?\s*$amd|) { |
| $content =~ s|^(.*\n#?\s*AddModule\s+[^\n]+\n)|$1$c$amd\n|sg; |
| } else { |
| $content =~ s|^(.*\n)#?\s*$amd[^\n]*\n|$1$c$amd\n|sg; |
| } |
| } |
| if (@lmd or @amd) { |
| if (open(FP, ">$CFG_SYSCONFDIR/$CFG_TARGET.conf.new")) { |
| print FP $content; |
| close(FP); |
| system("cp $CFG_SYSCONFDIR/$CFG_TARGET.conf $CFG_SYSCONFDIR/$CFG_TARGET.conf.bak && " . |
| "cp $CFG_SYSCONFDIR/$CFG_TARGET.conf.new $CFG_SYSCONFDIR/$CFG_TARGET.conf && " . |
| "rm $CFG_SYSCONFDIR/$CFG_TARGET.conf.new"); |
| } else { |
| notice("unable to open configuration file"); |
| } |
| } |
| } |
| } |
| |
| sub error{ |
| print STDERR "apxs:Error: $_[0].\n"; |
| } |
| |
| sub notice{ |
| print STDERR "$_[0]\n"; |
| } |
| |
| ##EOF## |
| __DATA__ |
| ## |
| ## Makefile -- Build procedure for sample %NAME% Apache module |
| ## Autogenerated via ``apxs -n %NAME% -g''. |
| ## |
| |
| builddir=$(shell pwd) |
| top_srcdir=%PREFIX% |
| top_builddir=%PREFIX% |
| include %PREFIX%/build/special.mk |
| |
| # the used tools |
| APXS=apxs |
| APACHECTL=apachectl |
| |
| # additional defines, includes and libraries |
| #DEF=-Dmy_define=my_value |
| #INC=-Imy/include/dir |
| #LIB=-Lmy/lib/dir -lmylib |
| |
| # the default target |
| all: local-shared-build |
| |
| # install the shared object file into Apache |
| install: install-modules |
| |
| # cleanup |
| clean: |
| -rm -f mod_%NAME%.o mod_%NAME%.lo mod_%NAME%.slo mod_%NAME%.la |
| |
| # simple test |
| test: reload |
| lynx -mime_header http://localhost/%NAME% |
| |
| # 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/stop |
| # procedures |
| start: |
| $(APACHECTL) start |
| restart: |
| $(APACHECTL) restart |
| stop: |
| $(APACHECTL) stop |
| |
| -=#=- |
| mod_%NAME%.la: mod_%NAME%.slo |
| $(SH_LINK) -rpath $(libexecdir) -module -avoid-version mod_%NAME%.lo |
| DISTCLEAN_TARGETS = modules.mk |
| shared = mod_%NAME%.la |
| -=#=- |
| /* |
| ** 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 modules directory |
| ** by running: |
| ** |
| ** $ apxs -c -i mod_%NAME%.c |
| ** |
| ** Then activate it in Apache's %TARGET%.conf file for instance |
| ** for the URL /%NAME% in as follows: |
| ** |
| ** # %TARGET%.conf |
| ** LoadModule %NAME%_module modules/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.3.4 (Unix) |
| ** Connection: close |
| ** Content-Type: text/html |
| ** |
| ** The sample page from mod_%NAME%.c |
| */ |
| |
| #include "httpd.h" |
| #include "http_config.h" |
| #include "http_protocol.h" |
| #include "ap_config.h" |
| |
| /* The sample content handler */ |
| static int %NAME%_handler(request_rec *r) |
| { |
| if (strcmp(r->handler, "%NAME%")) { |
| return DECLINED; |
| } |
| r->content_type = "text/html"; |
| |
| if (!r->header_only) |
| ap_rputs("The sample page from mod_%NAME%.c\n", r); |
| return OK; |
| } |
| |
| static void %NAME%_register_hooks(apr_pool_t *p) |
| { |
| ap_hook_handler(%NAME%_handler, NULL, NULL, APR_HOOK_MIDDLE); |
| } |
| |
| /* Dispatch list for API hooks */ |
| module AP_MODULE_DECLARE_DATA %NAME%_module = { |
| STANDARD20_MODULE_STUFF, |
| 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%_register_hooks /* register hooks */ |
| }; |
| |