#!perl

BEGIN {
    $Is_Win32  = ($^O eq "MSWin32");
    $Is_Cygwin = ($^O =~ m/cygwin/g);

    if ($Is_Win32) {
        require 5.004_02;
        require Win32;
    }
    elsif ($Is_Cygwin) {
        require 5.005_03;
    }
    else {
        require 5.003_97;
    }
}

sub MMN_130 () { 19980527 }

use Config ();
use Cwd;
use DirHandle ();
use ExtUtils::MakeMaker;
use File::Basename qw(dirname basename);
use File::Compare ();
use File::Copy qw(cp);
use File::Path qw(mkpath rmtree);
use FileHandle ();

*Config = \%Config::Config unless %Config;

my %vcache = ();                #SERVER_VERSION
my %mcache = ();                #MODULE_MAGIC_NUMBER

#version 1.5 that ships with 5.003 is broken!
*cp = sub { 
    system "cp @_";
    for (@_) {
        -e $_ or die $!;
    }
} if $File::Copy::VERSION < 2.0;

my $Is_dougm = defined $ENV{USER} && $ENV{USER} eq "dougm";
my $USE_THREADS;
my $thrlib = join '|', qw(-lpthread);

if ($] < 5.005_60) {
    $USE_THREADS = defined $Config{usethreads} &&
        $Config{usethreads} eq "define";
}
else {
    $USE_THREADS = defined $Config{use5005threads} &&
        $Config{use5005threads} eq "define";
}

#hmm, seems the #include flip/flop isn't needed anymore
#so ignore the stuff above for now
$USE_THREADS = $ENV{PERL_USE_THREADS} || 0;

require "./lib/mod_perl.pm";
$VERSION = $mod_perl::VERSION = $mod_perl::VERSION;

{
    $VERSION =~ s/(\d\d)(\d\d)$/$1_$2/;
}

{
    local *FH;
    open FH, "Changes";
    while (<FH>) {
        if (/^=item.*-(dev|rc\d+)/) {
            $VERSION .= "-$1";
            last;
        }
        last if /^=item/;
    }
    close FH;
}

use subs qw(iedit asrc);

if ($] < 5.004_04) {
    print <<EOF;
I see you're building with Perl $]
It is strongly recommended that you upgrade to 5.004_04 or higher,
as there are memory leaks present in lower versions or Perl.
EOF
    sleep 1;
}

%Apache::MyConfig::Setup = ();
eval 'require Apache::MyConfig' ;

$APACHE_SRC_DEFAULT = $@ ?
    '../apache_x.x/src'  :
    $Apache::MyConfig::Setup{Apache_Src} ;

#workaround bug in 5.8.0-RC1 where Cwd::cwd creates $ENV{IFS}
#which makes apache configure fall apart on solaris
my $ifs_exists = exists $ENV{IFS};
my $PWD = cwd;
delete $ENV{IFS} unless $ifs_exists;

$ENV{APACHE_CWD} = $PWD;
$ENV{PERL5LIB} = join ':', "$PWD/lib", $ENV{PERL5LIB};

my %SSL = (
           "modules/ssl/apache_ssl.c" => "Ben-SSL",
           "apache_ssl.c" => "Ben-SSL",
           "mod_ssl.h"   => "Stronghold",
           "modules/modssl" => "Stronghold",
          );

unless (-e "t/docs/test.shtml") {
    cp "t/docs/test.html", "t/docs/test.shtml";
}

for (qw(.htaccess hooks.txt)) {
    my $file = "t/docs/$_";
    local *FH;
    open FH, ">$file" or
        die "can't write test file: $file: $!";
    chmod 0666, $file;
    close FH;
}

chmod 0644, "t/conf/mod_perl_srm.conf";

mkdir "t/logs", 0777;
chmod 0777, "t/logs";

unless ($Is_Win32) {
    system "chmod a+x t/net/perl/* t/net/perl/io/*";
}

#generated by us at one time or another
my(@do_clean) = qw{
                   t/docs/.htaccess
                   t/docs/hooks.txt
                   src/Configuration
                   lib/Apache/MyConfig.pm
                   Apache/Apache.xs
                   Constants/Constants.xs
                   t/modules/ssi.t
                   t/logs/error_log
                   t/conf/srm.conf
                   t/conf/dev-null
                   t/logs/httpd.pid
                   src/modules/perl/mod_perl_version.h
                   t/net/perl/cgi.pl
                   t/report
                   t/TEST
                   t/httpd
                   apaci/find_source
                   apaci/apxs_cflags
                   apaci/mod_perl.config
               };
#t/conf/httpd.conf
#t/net/config.pl

for (@do_clean) { unlink $_ }

unless ($Is_Win32) {
    rename "t/conf/httpd.conf", "t/conf/httpd.conf.old";
}

rmtree "t/docs/stacked", 0, 0;

gen_script("t/net/perl/cgi.pl");
gen_script("t/report");
gen_script("t/TEST");
gen_script("apaci/find_source");
gen_script("apaci/apxs_cflags");
gen_script("apaci/perl_config", "$PWD/lib");
gen_script("apaci/load_modules.pl");

write_version_h("src/modules/perl");

my(@test_pre_init) = qq(
  test_pre_init:
);

# Automatic setup support
my(@adirs, %seen, %mft_map, %vers_map, $src_dir, $vers, $conf, $ans);
%vers_map = (
             '1.1.1' => "Makefile.tmpl",
             '1.1.3' => "Makefile.tmpl",
             '1.2'  => "Makefile.tmpl-1.2",
             '1.1.1Xcert-Sentry' => "Makefile.tmpl-XCert",
             '1.1.1Ben-SSL' => "Makefile.tmpl-Ben-SSL",
             '1.1.3Ben-SSL' => "Makefile.tmpl-Ben-SSL",
             '1.2Ben-SSL' => "",
             NONE => "",
            );

$LIBPERL = "DEFAULT";
$USE_APACI = $USE_DSO = $USE_APXS = 0;
$WITH_APXS = "";
$APACI_ARGS = "";
@APACI_ARGS = ();
$EVERYTHING = $EXPERIMENTAL = 0;
$PERL_DEBUG = "";
$PERL_DESTRUCT_LEVEL = "";
$PERL_STATIC_EXTS = "";
$PERL_USELARGEFILES = 1;
$PERL_EXTRA_CFLAGS = "";
$PERL_EXTRA_LIBS = "";
$SSLCacheServerPort = 8539;
$SSL_BASE = ""; 
$Port = $ENV{HTTP_PORT} || 8529;
#so Doug can 'make test' different-builds@sametime/samebox
if(!$Is_Win32 and $ENV{RANDOM_PORT} and $$ > 8000 and $$ < 30000) {
    $PORT ||= $$;
    print "I'll use Port $PORT\n";
}
$PORT ||= $Port;
$TARGET = "";
$DO_HTTPD = $ENV{DO_HTTPD} || 0;
$NO_HTTPD = $ENV{NO_HTTPD} || 0;
$PREP_HTTPD = 0;
$PERL_TRACE = 0;
$ALL_HOOKS  = 0;
$APACHE_SRC = "";
$APACHE_PREFIX = "";
$APACHE_HEADER_INSTALL = 1;
$PERL_SECTIONS = 0;
$PERL_SSI = 0;
$ADD_VERSION = 1;
$STATIC = 1;
$DYNAMIC = 0;
$CONFIG = "";
$ADD_MODULE = "";
$PERL_DIRECTIVE_HANDLERS = 0;
$PERL_TABLE_API = 0;
$PERL_LOG_API = 0;
$PERL_URI_API = 0;
$PERL_UTIL_API = 0;
$PERL_FILE_API = 0;
$PERL_CONNECTION_API = 1; #these two were split out late in the game
$PERL_SERVER_API = 1;     #so they are on by default 
$PERL_RUN_XS = 0;
$MOD_PERL_PREFIX;

my %experimental = map { $_,1 } qw{
                                   PERL_AUTOPRELOAD
                                   PERL_RUN_XS
                                   PERL_MARK_WHERE
                                   DO_INTERNAL_REDIRECT
                                   PERL_TIE_SCRIPTNAME
                                   PERL_STASH_POST_DATA
                                   XS_IMPORT
                                   PERL_SAFE_STARTUP
                                   PERL_DEFAULT_OPMASK
                                   PERL_ORALL_OPMASK
                               };

my %PassEnv = map { $_,1 } qw(SSL_BASE);

my @mp_args = (keys %PassEnv,
               qw(EXPERIMENTAL EVERYTHING DO_HTTPD NO_HTTPD CONFIG ADD_MODULE 
                  APACHE_PREFIX
                  USE_APACI USE_DSO USE_APXS WITH_APXS APACI_ARGS PREP_HTTPD
                  ALL_HOOKS ADD_VERSION STATIC DYNAMIC PORT XS_IMPORT));

sub is_mp_arg {
    my $arg = shift;

    return 1 if $experimental{$arg};

    for (@mp_args) {
        return 1 if $arg eq $_;
    }

    return 0;
}

#callback hooks
@callback_hooks = qw{
                     PERL_DISPATCH
                     PERL_CHILD_INIT PERL_CHILD_EXIT
                     PERL_POST_READ_REQUEST PERL_TRANS PERL_HEADER_PARSER
                     PERL_ACCESS PERL_AUTHEN PERL_AUTHZ 
                     PERL_TYPE PERL_FIXUP
                     PERL_HANDLER PERL_LOG 
                     PERL_INIT PERL_CLEANUP PERL_RESTART
                     PERL_STACKED_HANDLERS 
                     PERL_METHOD_HANDLERS
                     PERL_DIRECTIVE_HANDLERS
                     PERL_TABLE_API
                     PERL_LOG_API
                     PERL_URI_API
                     PERL_UTIL_API
                     PERL_FILE_API
                     PERL_CONNECTION_API
                     PERL_SERVER_API
                 };

$callback_alias{PERL_INIT} = "PERL_HEADER_PARSER";
$callback_alias{PERL_CLEANUP} = "PERL_LOG";
%callback_hooks = map { $_,0 } @callback_hooks;
$callback_hooks{PERL_HANDLER} = 1; #PerlHandler always on
%cant_hook = ();

my @mm_args;
{
    my ($fh,$file);
    for (qw(./ ../ ./. ../.), "$ENV{HOME}/.") {
        last if $fh = FileHandle->new($file = $_."makepl_args.mod_perl");
    }
    if($fh) {
        print "Reading Makefile.PL args from $file\n";
        while(<$fh>) {
            chomp;
            s/^\s+//; s/\s+$//;
            next if /^#/ || /^$/;
            last if /^__END__/;
            if (/^APACI_ARGS/) {
                s/^APACI_ARGS=//;
                push @APACI_ARGS, $_;
            }
            else {
                unshift @ARGV, split /\s+/, $_;
            }
        }
        close $fh;
    }
    if (@APACI_ARGS) {
        unshift @ARGV, "APACI_ARGS=" . join(",", @APACI_ARGS);
    }
}

my $vcpp = ($Config{cc} =~ /^cl(\.exe)?$/);
my %win32_args;
my %win32_accept = map {$_ => 1}
    qw(APACHE_SRC INSTALL_DLL INSTALL_LIB DEBUG EAPI);

while($_ = shift) {
    ($k,$v) = split /=/, $_, 2;
    if ($vcpp) {
        if ($win32_accept{$k}) {
            $win32_args{$k} = ($k eq 'DEBUG' or $k eq 'EAPI') ? 1 : $v;
        }
        else {
            push @mm_args, $_;
        }
        next;
    }
    unless (/^(PERL|APACHE)/ or is_mp_arg($k)) {
        push @mm_args, $_;
    }
	
    if ($k eq 'PREFIX') {
        require File::Spec;
        $MOD_PERL_PREFIX =
            File::Spec->catfile(
                                $v,
                                $Config{'installstyle'},
                                'site_perl',
                                $Config{'version'},
                                $Config{'archname'}
                               );
    }

    $v = 1 unless defined $v;
    if($experimental{$k}) {
        $experimental{$k}++;
        $PERL_EXTRA_CFLAGS .= " -D${k}=1";
    }

    ${$k} = $v, next if defined ${$k};
    $callback_hooks{$k} = $v if exists $callback_hooks{$k};
}

my $win32_auto;
if ($vcpp and $win32_args{APACHE_SRC}) {
    $EVERYTHING = 1;
    my $fixed_apsrc = win32_fix_path($win32_args{APACHE_SRC}); 
    $APACHE_SRC =  -d "$fixed_apsrc/include" ? $fixed_apsrc  : 
        (-d "$fixed_apsrc/src/include" ? $fixed_apsrc . '/src' :
         die "Cannot find the Apache include directory under $fixed_apsrc");
    $win32_auto = 1;
    unless ($win32_args{INSTALL_DLL}) {
        my $w32_ap_mod = $fixed_apsrc . '/modules';
        $win32_args{INSTALL_DLL} = $w32_ap_mod if -d $w32_ap_mod;
    }
    unless ($win32_args{INSTALL_LIB}) {
        my $w32_ap_lib = $fixed_apsrc . '/libexec';
        $win32_args{INSTALL_LIB} = $w32_ap_lib if -d $w32_ap_lib;
    }
}

my %very_experimental = map {$_,1}
    qw(
       PERL_DEFAULT_OPMASK PERL_SAFE_STARTUP PERL_ORALL_OPMASK
       PERL_STARTUP_DONE_CHECK PERL_DSO_UNLOAD
      );

if ($EXPERIMENTAL) {
    for (keys %experimental) {
        next if $very_experimental{$_}; #have to *really* ask for this one
        next if $experimental{$_}++ > 1;
        $PERL_EXTRA_CFLAGS .= " -D$_=1";
    }
}

if ($experimental{PERL_DEFAULT_OPMASK} > 1) {
    $experimental{PERL_SAFE_STARTUP} = 2;
    $PERL_EXTRA_CFLAGS .= " -DPERL_SAFE_STARTUP=1";
}

for (keys %PassEnv) {
    $ENV{$_} = $$_ if $$_;
}

$USE_APACI = 1 if $USE_DSO;
if (0) {
    #if($USE_DSO or $USE_APXS and !$DO_HTTPD) {
    print "*" x 65, $/;
    print <<EOF;
* WARNING: mod_perl as a DSO is known to fail on most platforms *
*          We recommend linking mod_perl static instead         *
EOF
    print "*" x 65, $/;
    my $ans = prompt("Continue?", "n");
    if ($ans =~ /^n$/i) {
        print "Aborting build process\n";
        exit;
    }
}

if ($USE_APXS) {
    if(-e $USE_APXS and !(-d _)) {
        $WITH_APXS = $USE_APXS;
    }
    if (not -x $WITH_APXS and $USE_APXS and $APACHE_PREFIX) {
        for (qw(sbin bin)) {
            last if -e ($WITH_APXS = "$APACHE_PREFIX/$_/apxs");
        }
    }
    unless (-x $WITH_APXS) {
        chomp($WITH_APXS = `which apxs`);
    }

    print "Will configure via APXS";
    print " (apxs=$WITH_APXS)" if $WITH_APXS;
    print "\n";
    ++$NO_HTTPD;
}

system_sanity_check();

if ($PERL_USELARGEFILES and $] >= 5.006) {
    $PERL_EXTRA_CFLAGS .= " $Config{ccflags}";
}

# apache-1.3.xx won't compile with -D_GNU_SOURCE
$PERL_EXTRA_CFLAGS =~ s/-D_GNU_SOURCE//;

if ($USE_APACI) {
    print "Will configure via APACI";
    if ($USE_DSO) {
        print " (DSO enabled)";
    }
    $NO_HTTPD = 1 if $PREP_HTTPD;
    print "\n";
}

@ARGV = @mm_args;
$STATIC = 0 if $DYNAMIC;
$Configuration = $CONFIG || "Configuration";

for (keys %callback_alias) {
    $callback_hooks{$callback_alias{$_}}++ 
        if $callback_hooks{$_};
}

if ($EVERYTHING) {
    @callback_hooks{qw(PERL_STACKED_HANDLERS PERL_METHOD_HANDLERS)} = (1) x 2;
    for (qw(
           ALL_HOOKS PERL_SSI PERL_SECTIONS PERL_DIRECTIVE_HANDLERS
           PERL_LOG_API PERL_URI_API PERL_UTIL_API PERL_TABLE_API PERL_FILE_API
          )) {
        $$_ = 1;
    }
}

if ($ALL_HOOKS) {
    for (@callback_hooks) {
        next if /(Api|Table|Handler)s?$/i;
        $callback_hooks{$_}++;
    }
}

if ($DYNAMIC) {
    $PERL_DIRECTIVE_HANDLERS = $PERL_TABLE_API = $PERL_FILE_API =
        $PERL_LOG_API = $PERL_URI_API = $PERL_UTIL_API = 1;
}

my @xs_modules = qw {
                     Apache Apache::Constants
                 };

if ($Is_Win32) {
    $NO_HTTPD = 1;
    $PERL_DIRECTIVE_HANDLERS = 1;
}

unless ($NO_HTTPD && !$PREP_HTTPD) {
    for $src_dir ($APACHE_SRC, <../apache*/src>, 
                  <../stronghold*/src>, </usr/local/stronghold*/src>,
                  "../src", "./src")
        {
            next unless -d $src_dir;
            next if $seen{$src_dir}++;
            next unless $vers = httpd_version($src_dir);
            unless(exists $vers_map{$vers}) {
                print STDERR "Apache version '$vers' unsupported\n";
                next;
            }
            $mft_map{$src_dir} = $vers_map{$vers};
            #print STDERR "$src_dir -> $vers_map{$vers}\n";
            push @adirs, $src_dir;
            $modified{$src_dir} = (stat($src_dir))[9];
            last if $DO_HTTPD;
        }

    unless (@adirs) {
        print "Enter `q' to stop search\n";
        while(1) {
            print "Please tell me where I can find your apache src\n" ; 
            $src_dir = prompt("", $APACHE_SRC_DEFAULT);
            last if $src_dir eq "q";
            if(-d $src_dir) {
                push @adirs, $src_dir;
                $mft_map{$src_dir} = $vers_map{httpd_version($src_dir)};
                last;
            }
            else {
                print "Can't stat `$src_dir'\n";
            }
        }
    }
}

if ($PERL_EXTRA_CFLAGS) {
    $PERL_EXTRA_CFLAGS = join(" ", split(",",  $PERL_EXTRA_CFLAGS));
    $PERL_EXTRA_CFLAGS =~ s/\s+/ /g;
}

if ($PERL_DEBUG) {
    my $lib = "$Config{archlibexp}/CORE/libperld$Config{lib_ext}";
    if (-e $lib) {
		$LIBPERL = "-lperld";
		$libperl = " -- $LIBPERL";
    }
    $PERL_EXTRA_CFLAGS .= " -g";
    $PERL_TRACE=1;
    $PERL_DESTRUCT_LEVEL=2;

    print "DEBUG mode...\n";
    print "...adding `-g' to EXTRA_CFLAGS\n";
    print "...turning on PERL_TRACE\n";
    print "...setting PERL_DESTRUCT_LEVEL=2\n";
    print "...linking against libperld\n" if $libperl;

    sleep(1);
}

$PERL_EXTRA_CFLAGS .= " -DPERL_DESTRUCT_LEVEL=$PERL_DESTRUCT_LEVEL"
    if $PERL_DESTRUCT_LEVEL;

for $adir (sort {$modified{$b} <=> $modified{$a}} @adirs) {
    $conf = "$adir/$Configuration";
    $httpd_h = asrc($adir)."/httpd.h";

    if (-e $httpd_h) {
        unless($NO_HTTPD and not $DYNAMIC and not $PREP_HTTPD) {
            unless($DO_HTTPD) {
                $ans = prompt("Configure mod_perl with $adir ?", "y");
                next unless $ans =~ /^y$/i;
            }
            $APACHE_SRC = $adir;
            $IsBenSSL = -e "$adir/apache_ssl.c";
            last unless(-e $conf || -e "$conf.tmpl"); #building from 'make offsite-tar' 
        }

        #++$NO_HTTPD if $USE_APACI;
        my $mmn = magic_number($APACHE_SRC);
        if (($mmn < MMN_130) and $USE_APACI) { #1.3.0
            print "Sorry, need 1.3.0+ for USE_APACI\n";
            $USE_APACI = $USE_DSO = 0;
        }

        for my $api (qw(LOG URI UTIL FILE TABLE)) {
            local $_ = join "_", "PERL", $api, "API";
            if (($mmn < MMN_130) and $$_) { #1.3.0
                $$_ = 0;
                $cant_hook{$_} = "(need 1.3.0 or higher)";
            }
        }

        if ($USE_DSO and $PERL_SSI) {
            $PERL_SSI=0;
            $cant_hook{PERL_SSI} = "(doesn't work w/ USE_DSO=1)";
        }

        unless ($DO_HTTPD or $NO_HTTPD) {
            $ans = prompt("Shall I build httpd in $adir for you?", "y");
            ++$NO_HTTPD, ++$PREP_HTTPD unless $ans =~ /^y$/i;
        }

        if ($NO_HTTPD) {
            #must generate Makefile.config for 1.3bx
            unless (-e "$adir/Makefile.config") {
                my $cfgfile = $CONFIG ? $CONFIG : "Configuration";
                print "(cd $adir && ./Configure -file $cfgfile)";
            }
        }

        #copy the source files
        if (!$NO_HTTPD or $USE_APACI or $PREP_HTTPD) {
            mkpath "$adir/modules/perl";
            #ignore make's output here
            `(cd $adir/modules/perl && make clean 2> /dev/null)`;

            local *MANI;
            open MANI, "MANIFEST" or die "open MANIFEST $!";
            my $atopdir = dirname($adir);

            unlink "$atopdir/perlxsi.c";
            #only rm and cp files mod_perl ships with
            while(<MANI>) {
                next unless m,^src/modules/perl/,; chomp;
                #print "rm -f $adir/$_\n";
                unlink "$atopdir/$_";
                next if not m,.+\.(xs|c|h)$, and $USE_APACI;
                next if $DYNAMIC and /\.xs$/;
                #print "cp $_ $atopdir/$_\n" if $USE_APACI;
                my $dest = "$atopdir/$_";
                cp $_, $dest;
                #$mani_src{$_}++;
            }
            close MANI;

            cp "src/modules/perl/mod_perl_version.h",
                "$atopdir/src/modules/perl/mod_perl_version.h";

            if ($USE_APACI) {
                open MANI, "MANIFEST" or die "open MANIFEST $!";
                while(<MANI>) {
                    next unless m,^apaci/,; chomp;
                    s/\.PL$//;
                    (my $to = $_) =~ s,^apaci/,src/modules/perl/,;
                    unlink "$atopdir/$to";
                    print "cp $_ $atopdir/$to\n";
                    my $dest = "$atopdir/$to";
                    cp $_, $dest;
                    chmod 0755, $dest if -x $_;
                }
                close MANI;
            }
        }

        ($APACHE_ROOT = $APACHE_SRC) =~ s,/src/?$,,;

        last if $NO_HTTPD; # or $USE_APACI;

        unless (-e "src/Configuration" and (-M "src/Configuration" < -M $conf) and not $USE_APACI) {
            unless (-e $conf) {
                cp "$conf.tmpl", $conf;
            }
            cp $conf, "src/Configuration";
            $conf = "src/Configuration";

            conf_fixup("$adir/Makefile.tmpl", $conf);
        }
    }

    unless ($NO_HTTPD || $USE_APACI) {
        $conf = "src/Configuration";
        my ($dash_make, $cfgfile);
        $dash_make = " -make $PWD/src/$mft_map{$adir} "
            if $can_dash_make{asrc $adir} and $mft_map{$adir};
        #print STDERR "(cd $adir; ./Configure${dash_make} -file $PWD/$conf)\n";
        $cfgfile = $CONFIG ? $CONFIG : "$PWD/$conf";
        $dash_make ||= "";
        system "(cd $adir && ./Configure${dash_make} -file $cfgfile)";

        open FH, "$APACHE_SRC/Makefile" or 
            die "can't open $APACHE_SRC/Makefile $!";
        while(<FH>) {
            $SSL_BASE  ||= $1 if /^\s*SSL_BASE\s*=\s*(.*)/;
            $EXTRA_CFLAGS = $1 if /CFLAGS1\s*=\s*(.*)/;
            $SSLINCS = $1 if /SSLINCS\s*=\s*(.*)/;
        }
        close FH;

        if ($SSL_BASE) {
            $SSL_INCLUDE = " -I$SSL_BASE/include ";
            $SSL_CFLAGS = "-DAPACHE_SSL $SSL_INCLUDE";
        }

        #stronghold
        if ($SSLINCS) {
            $SSL_INCLUDE = " $SSLINCS ";
            $SSL_CFLAGS = "-DAPACHE_SSL $SSL_INCLUDE";
        }
    }

    print "EXTRA_CFLAGS: $EXTRA_CFLAGS\n" if $EXTRA_CFLAGS;
    print "SSL_CFLAGS: $SSL_CFLAGS\n" if $SSL_CFLAGS;
    last if $APACHE_SRC;
}

if ($PERL_DIRECTIVE_HANDLERS) {
    push @xs_modules, "Apache::ModuleConfig";
    $callback_hooks{PERL_DIRECTIVE_HANDLERS} = 1;
}

#if($PERL_RUN_XS or $experimental{PERL_RUN_XS} > 1) {
if (0) {
    my $mmn    = $USE_APXS ? MMN_130 : magic_number($APACHE_SRC);
    if($mmn >= MMN_130) {
        push @xs_modules, "Apache::PerlRunXS";
    }
    else {
        $PERL_RUN_XS = 0;
        $experimental{PERL_RUN_XS} = 0; 
        print "Sorry, need 1.3.0+ for Apache::PerlRunXS\n";
    }
}

for (qw(Log URI Util Connection Server File Table)) {
    my $s = "PERL_".uc($_)."_API";
    if($$s or $Is_Win32) {
        push @xs_modules, "Apache::$_";
        $callback_hooks{$s} = 1;
    }
}

my @xs_mod_snames = map { (my $s = $_) =~ s/.*:://; $s } @xs_modules;

win32_setup() if $Is_Win32;

if ($DYNAMIC) {
    print "Will build Apache::* extensions dynamic\n";
    for (@xs_mod_snames) {
        cp "src/modules/perl/${_}.xs", "${_}/${_}.xs";
    }
}

if ($APACHE_SRC or $USE_APXS) {
    ++$STATIC if grep { $_ eq lc($Config{osname}) } qw(aix svr4 unixware);

    my $mmn    = $USE_APXS ? MMN_130 : magic_number($APACHE_SRC);
    my $httpdv = $USE_APXS ? 130     : httpd_version($APACHE_SRC,1);

    unless ($httpdv >= 130) {
        phat_warn("Apache Version 1.3.0 required, aborting...");
        exit(1);
    }

    if ($httpdv >= 130) {
        if($callback_hooks{PERL_CHILD_INIT}) {
            $My::child_init++;
        }
    }
    else {
        $callback_hooks{PERL_CHILD_INIT} = 0;
        $cant_hook{PERL_CHILD_INIT} = 
            "(need 1.3.0 or higher)";
    }

    if ($mmn >= 19970728) {
        $callback_hooks{PERL_CHILD_EXIT} = $My::child_exit =
            $callback_hooks{PERL_CHILD_INIT} = $My::child_init = 1;
    }
    else {
        $callback_hooks{PERL_CHILD_EXIT} = 0;
        $cant_hook{PERL_CHILD_EXIT} = 
            "(need 1.3.0 or higher)";
    }

    unless($mmn >= 19970825) {
        $callback_hooks{PERL_POST_READ_REQUEST} = 0;
        $cant_hook{PERL_POST_READ_REQUEST} = 
            "(need 1.3.0 or higher)";
    }

    setup_for_static() unless $USE_APXS;

    iedit "$APACHE_SRC/modules/perl/Makefile",
        "s!^PERL\\s*=.*!PERL=$Config{'perlpath'}!" unless $USE_APACI or $USE_APXS;

    for (@callback_hooks) {
        ($k,$v) = ($_,$callback_hooks{$_});

        unless ($USE_APACI or $USE_APXS) {
            iedit "$APACHE_SRC/modules/perl/Makefile", "s/^$k /#$k /" if $v;
        }

        $why = ($cant_hook{$k} || "(enable with $k=1)") unless $v;
        $k =~ s/([A-Z]+)/ucfirst(lc($1))/ge;
        $k =~ s/_//g;
        $k .= "Handler" unless $k =~ /(Api|Table|Handler)s?$/;
        push @mod_perl_hooks, $k;
        print $k . '.' x (28 - length($k));
        print $v ? "enabled\n" : "disabled $why\n";
    }

    unless($httpdv >= 120) {
        $PERL_SECTIONS = $PERL_SSI = 0;
        $cant_hook{PERL_SECTIONS} = $cant_hook{PERL_SSI} = 
            "(need 1.2.0 or higher)";
    }

    $PERL_SSI = 0 if $Is_Win32;
    unless ($Is_Win32) {
        for (qw(PERL_SECTIONS PERL_SSI), keys %experimental) {
            $k = $_;

            if ($experimental{$_}) {
                next unless $experimental{$_} > 1;
                print $k . '.' x (28 - length($k));
                print "enabled (experimental)";
            }
            else {
                $why = ($cant_hook{$_} || "(enable with $k=1)") unless $$_;
                $k =~ s/([A-Z]+)/ucfirst(lc($1))/ge;
                $k =~ s/_//g;
                $k =~ s/Ssi$/SSI/; #*shrug*
                push @mod_perl_hooks, $k;
                print $k . '.' x (28 - length($k));
                print $$_ ? "enabled" : "disabled $why\n";
            }

            print "\n";
            unless ($USE_APACI or $USE_APXS) {
                iedit "$APACHE_SRC/modules/perl/Makefile", "s/^($_) /#\$1 /"
                    if $$_;
            }
        }
    }

    unless ($USE_APACI or $USE_APXS) {
        iedit "$APACHE_SRC/modules/perl/Makefile", "s/^#TRACE/TRACE/" if $PERL_TRACE;
    }

    my $ssl_name = is_ssl();
    if ($ssl_name) {
        print "I see you are building with $ssl_name,\nI'll set the SSL flags in mod_perl's Makefile\n";

        if ($ssl_name =~ /stronghold/i) {
            my $skey;
            my $lfile;
            my $conf = "$APACHE_SRC/../conf/httpd.conf";
            if(-e $conf) {
                open FH, $conf;
                while(<FH>) {
                    chomp;
                    if(/^StrongholdKey/) {
                        $skey = $_;
                        last;
                    }
                    elsif(s/^StrongholdLicenseFile\s+//) {
                        $lfile = $_;
                        unless ($lfile =~ m:^/:) {
                            $lfile = "$PWD/$APACHE_SRC/../$lfile";
                        }
                    }
                }
                close FH;
            }

            if ($skey) {
                $StrongholdKey = $skey;
                print "Using $skey for 'make test'\n";
            }
            elsif (-e $lfile) {
                $StrongholdKey = join " ", 
                    "StrongholdLicenseFile", $lfile;
                print "Using $StrongholdKey for 'make test'\n";
            }
            else {
                print "Before running `make test', ",
                    "you must add your `StrongholdLicenseFile' to t/conf/httpd.conf\n"; 
            }
        }

        unless ($USE_APACI or $USE_APXS) {
            iedit "$APACHE_SRC/modules/perl/Makefile",	
                "s:^#APACHE_SSL.*:APACHE_SSL = $SSL_CFLAGS:";
        }
    }

    #my $incdir = ($mmn >= 19970825) ? "../../main" : "../..";
    my $minc = asrc($APACHE_SRC);
    $minc =~ /(main|include)/;
    my $incdir = $1 ? "../../$1" : "../..";
    my $edit_note = quotemeta(<<EOF);
#### Start of Makefile.PL created section ####
#---------------------------------------------------------------------
# This Makefile is derived from:
# $PWD/src/modules/perl/Makefile 
# which comes with the mod_perl distribution and 
# written by mod_perl's Makefile.PL.
# Rerunning Makefile.PL overwrites this file. Consequently...

# DO NOT EDIT THIS FILES, EDIT
#    $PWD/src/modules/perl/Makefile
# INSTEAD
#---------------------------------------------------------------------

MOD_PERL_VERSION = $VERSION

INCDIR = $incdir

EOF

    unless ($USE_APACI or $USE_APXS) {
        iedit "$APACHE_SRC/modules/perl/Makefile", "s/^#__ORIGINAL__/$edit_note/";
    }

    if ($mmn >= 19970912 and not $USE_APACI and not $USE_APXS and not $Is_Win32) {     #1.3b1
        system "cat $APACHE_SRC/Makefile.config $APACHE_SRC/modules/perl/Makefile > /tmp/mpmf.$$";
        system "mv /tmp/mpmf.$$ $APACHE_SRC/modules/perl/Makefile";
    }

    if ($callback_hooks{PERL_TRANS}) {
        push @test_pre_init, 
            "\t", '$(CP) t/conf/mod_perl_srm.conf t/conf/srm.conf', "\n";
    }

    unless ($USE_APXS) {
        unless (-l "t/httpd" or $Is_Win32) {
            system "$Config{lns} $APACHE_SRC/httpd t/httpd";
        }
        write_extra_tests();
    }
}

unless (-e "t/net/config.pl") {
    cp "t/net/config.pl.dist", "t/net/config.pl";
}

init_config_pl() if $Is_Win32;

my (%win32_path);
if ($win32_auto) {
    require File::Spec;
    win32_inc_and_lib();
    win32_fix_dsp();
}

write_my_config($APACHE_SRC);

unless($Is_Win32 or -e "t/conf/httpd.conf" or ($NO_HTTPD && !$PREP_HTTPD)) {
    init_tests_and_config();
}

init_tests_and_config() if $USE_APXS;

sub init_config_pl {

    my $mmn = magic_number($APACHE_SRC) || 0;

    my $hf = FileHandle->new(">>t/net/config.pl") or 
        die "can't open t/net/config.pl $!";

    my $apaci_cfg = APACI->init;

    my ($k,$v);
    my (%all) = %callback_hooks;
    while (($k,$v) = each %experimental) {
        $all{$k} = ($experimental{$k} > 1) ? 1 : 0;
    }

    print $hf "%callback_hooks = (\n";

    while (($k,$v) = each %all) {
        print $hf "   $k => $v,\n";
        my $yes_no = $v ? "yes" : "no";
        print $apaci_cfg "$k = $yes_no\n" if $apaci_cfg;
    }

    print $hf "   MMN => $mmn,\n";
    print $hf "   USE_DSO => 1,\n" if $USE_DSO;
    print $hf ");\n1;\n";

    $hf->close;
    $apaci_cfg->close if $apaci_cfg;
}

sub init_tests_and_config {

    local *FH;
    open FH, ">t/conf/dev-null";
    print FH "#mod_ssl has a problem with /dev/null\n";
    close FH;

    cp "t/conf/httpd.conf-dist", "t/conf/httpd.conf";
    chmod 0644, "t/conf/httpd.conf";

    $uid = $>;
    $gid = $);

    #use only first value if $) contains more than one
    $gid =~ s/^(\d+).*$/$1/;

    $User  = $Is_Win32 ? "nobody" : 
        $ENV{APACHE_USER} || (getpwuid($uid) || "#$uid");
    $Group = $Is_Win32 ? "nogroup" : 
        $ENV{APACHE_GROUP} || (getgrgid($gid) || "#$gid");

    if ($User eq "root") {
        my $other = (getpwnam('nobody'))[0];
        $User = $other if $other;
    }
    if ($User eq "root") {
        print "Cannot run tests as User `$User'\n";
        $User = prompt("Which User?", "nobody");
        $Group = prompt("Which Group?", $Group); 
    }
    print STDERR "Will run tests as User: '$User' Group: '$Group'\n";

    if ($Port != $PORT) {
        iedit "t/conf/httpd.conf", "s/^(Port) .*/\$1 $PORT/";
        iedit "t/net/config.pl", "s/$Port/$PORT/;";
    }
    if ($experimental{PERL_SAFE_STARTUP} > 1) {
        if ($experimental{PERL_DEFAULT_OPMASK} < 2) {
            iedit "t/conf/httpd.conf", "s/^#(PerlOpmask)/\$1/";
        }
    }

    init_config_pl();

    if ($USE_APACI and not $PREP_HTTPD and not $USE_APXS) {
        my $shrpenv = $Config{shrpenv} || "";
        $shrpenv .= ' ' if $shrpenv;
        my $cmd = "CC=\"${shrpenv}$Config{cc}\" ";

        if ($PERL_EXTRA_CFLAGS) {
            $cmd .= qq(CFLAGS="$PERL_EXTRA_CFLAGS" );
        }
	
        if ($USE_DSO) {
            # override apache's notion of this flag
            $cmd .= qq(LDFLAGS_SHLIB_EXPORT="$Config{ccdlflags}" );

            #if Perl is linked with -lpthread, httpd needs tobe too
            if ($Config{libs} =~ /($thrlib)/) {
                $PERL_EXTRA_LIBS .= " $1";
            }
        }
        if ($PERL_EXTRA_LIBS) {
            $cmd .= qq(LIBS="$PERL_EXTRA_LIBS" );
        }
        $cmd .= "./configure " .
            "--activate-module=src/modules/perl/libperl.a";

        # Do not disable the rule EXPAT for Stronghold, since this
        # rule is not implementated yet and breaks the configure process.
        if (is_ssl() !~ /stronghold/i) {
            $cmd .= " --disable-rule=EXPAT";
        }

        if($USE_DSO) {
            $cmd .= " --enable-shared=perl";
        }
        if($APACI_ARGS) {
            $cmd .= " " . join " ", split(',', $APACI_ARGS);
        }
        if($APACHE_PREFIX and $APACI_ARGS !~ /--prefix=/)  {
            $cmd .= " --prefix=$APACHE_PREFIX";
        }
        if ($APACI_ARGS =~ /--target=(\S+)/) {
            $TARGET = $1;
        }
        if($ADD_MODULE) {
            for (split ",", $ADD_MODULE) {
                if (/^([a-zA-Z0-9][a-zA-Z0-9_]+)$/) {
                    $cmd .= " --enable-module=$1";
                }
                elsif (m:(src/modules/[^/]+/[^/]+)$:) {
                    $cmd .= " --activate-module=$1";
                }
            }
        }

        print "(cd $APACHE_ROOT && $cmd)\n";
        system "(cd $APACHE_ROOT && $cmd)";
    }

    if ($USE_APXS) {
        my $cmd = "./configure --with-perl=$^X";
        $cmd .= " --with-apxs=$WITH_APXS" if $WITH_APXS;
        system "(cd apaci && $cmd)";
    }

    #expand ./t to full path
    iedit "t/conf/httpd.conf", "s: \./t(\\S*): $PWD/t\$1:";

    for (qw(User Group)) {
        $$_ = qq{"$$_"} if $$_ =~ /\s/; # User takes one parameter
        iedit "t/conf/httpd.conf", "s/^$_ .*/$_ $$_/"; 
    }
    conf_append(<<EOF) if $IsBenSSL;
SSLDisable
SSLCacheServerPort $SSLCacheServerPort
SSLCacheServerPath /tmp  
EOF
    conf_append($StrongholdKey) if $StrongholdKey;
    if (is_ssl() =~ /stronghold/i) {
        iedit "t/conf/httpd.conf", "s:^SSL:#SSL:";
    }

    #phooey!
    my $v = httpd_version($APACHE_SRC, 1);
    my $mmn = magic_number($APACHE_SRC) || 0;

    conf_append("LockFile logs/mod_perl.lock") if $v >= 121 or $mmn >= MMN_130;
    conf_append("PerlChildInitHandler My::child_init") if $My::child_init;
    conf_append("PerlChildExitHandler My::child_exit") if $My::child_exit;
    conf_append("PerlTransHandler My::ProxyTest") 
        if $callback_hooks{PERL_TRANS} and 
            $callback_hooks{PERL_STACKED_HANDLERS} and
                $mmn > 19980270 and $Is_dougm;

    conf_append(<<EOF) if $callback_hooks{PERL_STACKED_HANDLERS}; 
<Location /chain>
SetHandler perl-script
PerlHandler Stacked::one Stacked::two Stacked::three Stacked::four
</Location>
EOF
}

{
    (my $pmv = $VERSION) =~ s/_//g;
    $pmv =~ s/-dev$//;
    my $hooks = "@mod_perl_hooks";
    my $dummy = "hooks=`$hooks'\n" unless $hooks;
    cp "lib/mod_perl_hooks.pm.PL", "lib/mod_perl_hooks.pm"; 

    if ($Is_Win32) {
        my @args = ($^X, '-spi.bak', '-e', "\"s/sub mod_perl::hooks.*/sub mod_perl::hooks { qw($hooks) }/\"", 'lib/mod_perl_hooks.pm');
        system(@args) == 0 or die "@args failed\n";
    }

    iedit "lib/mod_perl_hooks.pm",
        qq(s/sub mod_perl::hooks.*/sub mod_perl::hooks { qw($hooks) }/);

    require "lib/mod_perl_hooks.pm";
    my @list = mod_perl::hooks();

    unless ($Is_Cygwin) { # test doesn't seem to be needed, works for me (Per Einar)
        @list == @mod_perl_hooks or die "Edit of lib/mod_perl_hooks.pm failed $!\n";
    }

    unlink $Is_Win32 ? "lib/mod_perl_hooks.pm.bak" : "lib/mod_perl_hooks.pm~";
}

#checking for LWP code, borrowed from LWP's own Makefile.PL :-)
unless ($Is_Win32) {
    print "Checking CGI.pm VERSION..........";
    eval {
        require CGI;
    };
    if ($CGI::VERSION >= 2.39) {
        print "ok\n";
    }
    else {
        print "I suggest upgrading from $CGI::VERSION to 2.39+\n";
        sleep 2;
    }
    print "Checking for LWP::UserAgent......";
    eval {
        require LWP::UserAgent;
    };
    if ($@) {
        $no_lwp++;
        $missing_modules++;
        print "failed\n";
        print <<EOT;
$@
The libwww-perl library is needed to run the test suite.
Installation of this library is recommended, but not required.   

EOT
        sleep(2);  # Don't hurry too much
    }
    else {
        print "ok\n";
    }

    print "Checking for HTML::HeadParser....";
    eval {
        require HTML::HeadParser;
    };

    if ($@) {
        $no_lwp++;
        $missing_modules++;
        print "failed\n";
        print <<EOT;
$@
The HTML-Parser package is needed (by libwww-perl) to run the test suite.
EOT
        sleep(2);  # Don't hurry too much
    }
    else {
        print "ok\n";
    }
}

sub is_ssl {
    my $d = shift || $APACHE_SRC;

    for (keys %SSL) {
        #warn "looking for $APACHE_SRC/$_\n";
        return $SSL{$_} if -e "$d/$_";
    }

    return 0;
}

sub write_extra_tests {

    #ensure we can find blib/
    local *FH;
    open FH, ">t/docs/blib.pl";
    print FH "use lib qw(\n", 
        (map { "$PWD/$_\n" } qw(blib/lib blib/arch)),
            ");\n1;\n";
    close FH;

    for my $f (qw(.htaccess hooks.txt)) {
        open FH, ">t/docs/$f";
        print FH " ";
        close FH;
        chmod 0666, "t/docs/$f";#make sure httpd can write to it
    }

    if ($PERL_SSI) {
        cp "t/modules/ssi.test", "t/modules/ssi.t";
    }
    else {
        unlink "t/modules/ssi.t";	# might be there from prior run
    }

    mkdir "t/docs/subr", 0755;
    if ($Is_Win32) {
        open FH, ">t/docs/subr/index.html" 
            or die "Cannot open t/docs/subr/index.html: $!";
        print FH scalar(localtime);
        close FH;
    }
    else {
        system "date > t/docs/subr/index.html";
    }

    return unless 
        $callback_hooks{PERL_STACKED_HANDLERS} 
            and $callback_hooks{PERL_FIXUP};
    local *FH;
    my $meth_test;
    if ($callback_hooks{PERL_METHOD_HANDLERS}) {
        $meth_test = <<'EOF';
#see startup.pl
PerlFixupHandler MyClass->method 
PerlFixupHandler $MyClass::Object->method 
PerlFixupHandler MyClass 
PerlFixupHandler LoadClass
PerlFixupHandler LoadClass->method
EOF
    }

    my $dir = "t/docs/stacked";
    mkdir $dir, 0755;
    cp "t/docs/test.html", $dir;
    open FH, ">$dir/.htaccess";
    print FH <<EOF;
    $meth_test
PerlFixupHandler  Apache::Constants::OK Apache::Constants::DECLINED MyClass::method
EOF
    close FH;
}

cp "t/conf/httpd.conf", "t/httpd.conf";

if ($ENV{TEST_PERL_DIRECTIVES}) {
    #push @DIR, 't/TestDirectives';
    if($Is_dougm and $USE_THREADS) {
        delete $ENV{TEST_PERL_DIRECTIVES};
    }
    else {
        system "(cd t/TestDirectives && $^X Makefile.PL)";
    }
}

$TARGET ||= (is_ssl() ? "httpsd" : "httpd");

WriteMakefile(
              #DIR => \@DIR,
              NAME    => "mod_perl",
              VERSION => $VERSION,
              ($] < 5.005 ? () :
               (
                ABSTRACT => 'Embed a Perl interpreter in the Apache HTTP server',
                AUTHOR   => 'Doug MacEachern <dougm@pobox.com>',
               )),
              #should override `CCFLAGS', can't with older perls
              #CCDLFLAGS => "$Config{ccdlflags} $EXTRA_CFLAGS", 
              DEFINE => $EXTRA_CFLAGS, 
              macro   => {
                          PERL => $Config{'perlpath'},
                          OPCODE_FILE => "src/opcodes.txt",
                          APACHE_ROOT => $APACHE_ROOT,
                          APACHE_SRC => $APACHE_SRC,
                          ARCHNAME => $Config{archname},
                          HTTPD => $TARGET,
                          PORT => $PORT,
                          PWD => $PWD,
                          PERL5LIB_ENV => "PERL5LIB=$ENV{PERL5LIB}",
                          SHRPENV => $Config{shrpenv},
                          CVSROOT => 'cvs.apache.org:/home/cvs',
                         },
              'dist'    => {
                            COMPRESS=> 'gzip -9f', SUFFIX=>'gz',
                            CI => qq(ci -u -m\\"See Changes file\\"),
                           },
              clean   => {
                          FILES	=> "@do_clean",
                         }
             );

print "*** BSDI users: be sure to read the INSTALL `Notes' section ***\n"
    if $Config{osname} =~ /bsdos/i;

cleanup_for_static();

sub MY::dist_basics {
    my $self = shift;

    my $string = $self->MM::dist_basics;
    if($USE_APXS) {
        $string =~ s/(distclean\s+::\s+)/$1 apxs_distclean /;
    }

    return $string;
}

sub MY::clean {
    my $self = shift;

    my $string = $self->MM::clean(@_);
    if ($win32_auto) {
        $string .= sprintf 
            qq{\tmsdev src\\modules\\win32\\mod_perl.dsp \\\n} .
                qq{\t/MAKE "mod_perl - Win32 %s" /CLEAN\n}, 
                    ($win32_args{DEBUG} == 1) ? 'Debug' : 'Release';
        return $string;
    }
    unless($NO_HTTPD) {
        my $asrc = asrc($APACHE_SRC, "http_main.c");
        return $string unless $APACHE_SRC and -e "$asrc/http_main.c";
        $string .= "\t-cd \$(APACHE_SRC) && \$(MAKE) clean\n";
    }
    if ($USE_APXS) {
        $string .= "\t-cd ./apaci && \$(MAKE) clean\n";
    }

    $string;
}

sub MY::install {
    my $self = shift;

    my $string = $self->MM::install;
    my $add = "";
    if ($USE_APXS) {
        $add = "apxs_install";
    }
    elsif ($win32_auto and 
           ($win32_args{INSTALL_DLL} or $win32_args{INSTALL_LIB})) {
        $add = 'amp_install';
    }
    elsif ($USE_APACI) {
        if ($APACI_ARGS =~ /--prefix=/ or $APACHE_PREFIX) {
            $add = "apaci_install";
        }
    }
    if ($add and (!$NO_HTTPD and !$PREP_HTTPD) or $USE_APXS or $win32_auto) {
        $string =~ s/(pure_install\s+)(.*)/$1 $add $2/;
    }

    return $string;
}

sub MY::top_targets {
    my $self = shift;

    my $string = $self->MM::top_targets;
    return $string unless $USE_APXS or $USE_APACI or $APACHE_SRC or $win32_auto;

    if ($win32_auto) {
        $string =~ s/(pure_all\s+::.*\s+subdirs\s+)(.*)/$1 amp_dll $2/;
        $string .= sprintf qq{\namp_dll:\n} . 
            qq{\tmsdev src\\modules\\win32\\mod_perl.dsp \\\n} .
                qq{\t/MAKE "mod_perl - Win32 %s" /USEENV\n}, 
                    ($win32_args{DEBUG} == 1) ? 'Debug' : 'Release';
        if ($win32_args{INSTALL_DLL}) {
            $string .= sprintf qq{\namp_install:\n\t\$(CP) "%s" "%s"}, 
                "$win32_path{MODPERL_LIB}/mod_perl.so", 
                    $win32_args{INSTALL_DLL} .
                        ($win32_args{APACHE_VERS} < 1315 ?
                         '/ApacheModulePerl.dll' : '/mod_perl.so');
        }
        if ($win32_args{INSTALL_LIB}) {
            $string .= sprintf qq{\n\t\$(CP) "%s" "%s"}, 
                "$win32_path{MODPERL_LIB}/mod_perl.lib", 
                    $win32_args{INSTALL_LIB} . '/mod_perl.lib';
        }
        return $string;
    }

    if ($USE_APXS) {
	    $string =~ s/(pure_all\s+::\s+)(.*)/$1 apxs_libperl $2/;
    }
    elsif ($USE_APACI and !$PREP_HTTPD) {
        $string =~ s/(pure_all\s+::\s+)(.*)/$1 apaci_httpd $2/;
    }
    elsif ($APACHE_SRC) {
        return $string unless -f "$APACHE_SRC/$Configuration";
        my $asrc = asrc($APACHE_SRC, "http_main.c");
        if (-e "$asrc/http_main.c" and !$NO_HTTPD) {
            $string =~ s/(pure_all\s+::\s+)(.*)/$1 apache_httpd $2/;
        }
    }

    $string .= <<'EOF';

gen_exports:
	$(PERL) -I./lib -MExtUtils::testlib -MApache::Constants::Exports \
	-e 'Apache::Constants::Exports->gen_ctags' > Exports.c

gen_op_mask:
	$(PERL) -MExtUtils::testlib -MApache::Opcode \
	-e 'Apache::Opcode->gen_op_mask' -- $(OPCODE_FILE) > op_mask.c

update_op_mask: gen_op_mask
	@$(RM_F) $(APACHE_SRC)/modules/perl/mod_perl_opmask.o
	$(CP) op_mask.c $(APACHE_SRC)/modules/perl/op_mask.c

apxs_distclean:
	(cd ./apaci && $(MAKE) distclean)

apxs_libperl:
	(cd ./apaci && $(PERL5LIB_ENV) $(MAKE))

apxs_install: apxs_libperl
	(cd ./apaci && $(MAKE) install;)

apache_httpd: $(APACHE_SRC)/Makefile.tmpl
	(cd $(APACHE_SRC) && $(PERL5LIB_ENV) $(SHRPENV) $(MAKE) CC="$(CC)";)

apaci_httpd: 
	(cd $(APACHE_ROOT) && $(PERL5LIB_ENV) $(MAKE))

apaci_install: 
	(cd $(APACHE_ROOT) && $(MAKE) install)

tar_Apache:
	(cd $(INSTALLSITELIB)/$(ARCHNAME); \
            $(TAR) -cf $(PWD)/Apache.tar mod_perl.pm Apache.pm Apache auto/Apache; )

offsite-tar:
	$(CP) MANIFEST MANIFEST.orig
	echo src/Makefile.config >> MANIFEST
	$(CP) $(APACHE_SRC)/Makefile.config src/Makefile.config
	mkdir "src/include"
	$(PERL) -e 'for (<$(APACHE_SRC)/include/*.h>) {' \
	-e 'system "$(CP) $$_ src/include/";' \
	-e 's,^$(APACHE_SRC),,;' \
	-e 'system "echo src$$_ >> MANIFEST";' \
	-e '}' 
	$(MAKE) dist
	$(RM_RF) src/include/
	$(RM) src/Makefile.config
	$(MV) MANIFEST.orig MANIFEST

EOF

    $string;
}

sub MY::pasthru {
    my $self = shift;

    return unless $APACHE_SRC;

    chomp(my $str = $self->MM::pasthru);
    join $/, "$str\\", 
        "\t".'APACHE_SRC="$(APACHE_SRC)"\\', 
            "\t".'DEFINE="$(DEFINE)"', 
                "";
}

sub MY::test {
    my $self = shift;

    my $test = $self->MM::test;
    my $mmn = magic_number($APACHE_SRC);
    return <<'EOF' if $USE_APXS and not $Is_dougm;
test:
	@echo "Can't make test with APXS (yet)"
EOF
    return <<'EOF' if $USE_DSO and ($mmn <= 19980527) and not $Is_dougm;
test:
	@echo "Can't make test with DSO (yet)"
EOF

    my $script = "t/TEST";
    $script .= ".win32" if $Is_Win32;
    my $my_test = $Is_Win32 ? q(

test:	run_tests

) :

q(

test:	pure_all start_httpd run_tests kill_httpd

);
    my $have_so = $USE_DSO || ($APACI_ARGS =~ /--enable-shared=/);
    push @test_pre_init, "\t",
        './apaci/load_modules.pl $(APACHE_SRC)', "\n" if $have_so;

    join '', @test_pre_init,
        qq(
    MP_TEST_SCRIPT=$script
),
    q(
    TEST_VERBOSE=0

kill_httpd:
	kill `cat t/logs/httpd.pid`
	@$(RM_F) t/conf/srm.conf
	@$(RM_F) t/logs/mod_perl.lock*
	$(RM_F) t/logs/httpd.pid
	$(RM_F) t/logs/error_log

start_httpd: test_pre_init
	@(cd t/conf; test -f httpd.conf || cp httpd.conf-dist httpd.conf)
	@(cd t/net; test -f config.pl || cp config.pl.dist config.pl)
	@$(TOUCH) t/conf/srm.conf
	$(APACHE_SRC)/$(HTTPD) -f `pwd`/t/conf/httpd.conf -X -d `pwd`/t &
	@echo httpd listening on port $(PORT)
	@echo will write error_log to: t/logs/error_log
	@echo "letting apache warm up...\c"
	@sleep 2
	@echo done

start_httpd_fork:
	$(APACHE_SRC)/$(HTTPD) -f `pwd`/t/conf/httpd.conf -d `pwd`/t

rehttpd:   kill_httpd start_httpd

run_tests:
	$(FULLPERL) $(MP_TEST_SCRIPT) $(TEST_VERBOSE)
),

$my_test,

q(

test_report:
	$(MAKE) test | t/report
);
}

use File::Find;

sub MY::subdirs {
    my $self = shift;

    if ($ENV{TEST_PERL_DIRECTIVES}) {
        push @{$self->{DIR}}, "t/TestDirectives";
    }

    $self->MM::subdirs(@_);
}

sub wanted {

    return unless /\.h$/ or /os-inline\.c$/;

    (my $d = $File::Find::dir) =~ s:^\Q$APACHE_SRC::;
    $d =~ s:^/::;

    my $from = "$File::Find::dir/$_";
    my $to   = '$(INST_ARCHLIB)/' . "auto/Apache/include/";
    $to .= "$d/" if $d;
    $to .= $_;

    $My::self->{PM}->{$from} = $to;
}

sub win32_mph {

    return unless /\.h$/ or /os-inline\.c$/;

    (my $d = $File::Find::dir) =~ s:^\Q$MODPERL_SRC::;
    $d =~ s:^/::;
    my $from = "$File::Find::dir/$_";
    my $to   = '$(INST_ARCHLIB)/' . "auto/Apache/include/modules/perl/";
    $to .= "$d/" if $d;
    $to .= $_;

    $My::self->{PM}->{$from} = $to;
}

sub MY::post_initialize {
    my $self = shift;

    return unless $APACHE_HEADER_INSTALL;

    my ($ap_src, $ap_inc);
    if ($APACHE_SRC) {
        $ap_src = $APACHE_SRC;
        $ap_inc = "$ap_src/include";
    }
    elsif ($USE_APXS) {
        #$base = `$WITH_APXS -q INCLUDEDIR`;
        $ap_inc = $ap_src = 'src'; #just install mod_perl headers
    }

    return unless $ap_src and -d $ap_src;

    $My::self = $self;
    {
        local $APACHE_SRC = $ap_src;
        finddepth(\&wanted, $ap_src);
    }
    if ($Is_Win32) {
      	local $MODPERL_SRC = win32_fix_path($PWD) . '/src/modules/perl';
        finddepth(\&win32_mph, $MODPERL_SRC);
    }

    $self->{PM}{"Apache/typemap"} = '$(INST_ARCHLIB)/' . "auto/Apache/typemap";
    $self->{PM}{"apaci/mod_perl.exp"} = '$(INST_ARCHLIB)/' . "auto/Apache/mod_perl.exp";
    for (qw(ap_config_auto.h)) {
        my $from = "$ap_inc/$_";
        my $to = '$(INST_ARCHLIB)/' . "auto/Apache/include/$_";
        unless ($self->{PM}->{$from}) {
            $self->{PM}->{$from} = $to;
            my @args = ($Config{perlpath}, '-MExtUtils::Command', 
                        '-e', 'touch', $from);
            system(@args) == 0
                or die "system @args failed: $?";
        }
    }

    '';
}

sub MY::postamble {

    return <<'EOF';
tag :
	svn copy https://svn.apache.org/repos/asf/perl/modperl/branches/1.x  https://svn.apache.org/repos/asf/perl/modperl/tags/$(VERSION_SYM)
	@echo update mod_perl.pm VERSION now

EOF
}

#'

sub MY::manifypods {
    my $self = shift;

    my $ver = $self->{VERSION} || "";
    local($_) = $self->MM::manifypods(@_);
    s/pod2man\s*$/pod2man --release mod_perl-$ver/m;

    $_;
}

sub fold_dots {
    my $v = shift;

    $v =~ s/\.//g;
    $v .= "0" if length $v < 3;

    $v;
}

sub vcache {
    my ($v,$dir) = @_;

    $vcache{$dir} = fold_dots($v);
}

sub httpd_version {
    my ($dir, $vnumber) = @_;

    local $^W=0;
    $dir = asrc($dir) || "";
    if ($vnumber) {
        return $vcache{$dir} if $vcache{$dir};
    }
    my $fh = FileHandle->new("$dir/httpd.h") or return;
    my ($server, $version, $rest);
    my ($fserver, $fversion, $frest);
    my ($string, $extra, @vers);
    while (<$fh>) {
        next unless /^#define/;
        s/SERVER_PRODUCT \"/\"Apache/; #1.3.13
        next unless s/^#define\s+SERVER_(BASE|)(VERSION|REVISION)\s+"(.*)\s*".*/$3/;
        unless (m:/:) {
            $_ = "Apache/$_"; #1.3.14, argh
        }
        chomp ($string = $_);

        #print STDERR "Examining SERVER_VERSION '$string'...";
        #could be something like:
        #Stronghold-1.4b1-dev Ben-SSL/1.3 Apache/1.1.1 
        @vers = split /\s+/, $string;
        foreach (@vers) {
            next unless ($fserver,$fversion,$frest) =  
                m,^([^/]+)/(\d\.\d+\.?\d*)([^ ]*),i;
            #print STDERR "match ($fserver,$fversion,$frest)\n";  
            if ($fserver =~ /Xcert-Sentry/i or $fserver eq "Ben-SSL") {
                $extra ||= $fserver;
                #print STDERR "I see $fserver/$fversion, ok\n";
                next;
            }

            if ($fserver eq "Apache") {
                ($server, $version) = ($fserver, $fversion);
                if ($version eq '1.2' and $frest =~ s/^b(\d+).*/$1/) {
                    if ($frest >= 8 and is_ssl($dir)) {
                        $do_link_swap++;
                        $can_dash_make{$dir}++;

                        return $vnumber ? vcache($version,$dir) : "NONE";
                    }
                    warn "Apache/1.2b$frest is not supported, upgrade to 1.2.0.\n";
                    return undef;
                }
                elsif ($version >= 1.2) {
                    $do_link_swap++ if is_ssl($dir);
                    $can_dash_make{$dir}++;
                    return $vnumber ? vcache($version,$dir) : "NONE";
                }
            }
            else {
                #print STDERR "'$fserver/$fversion' unrecognized.\n";
                next;
            }
            print STDERR "Found $fserver '$fversion' in $dir/httpd.h\n";
        }
    }
    $fh->close;

    #print STDERR "return $version$extra\n";
    return($version.$extra);
}

use lib "./lib";
use Apache::src ();

sub magic_number {
    my $d = asrc shift;

    my $src = Apache::src->new;
    $src->dir($d);

    return($mcache{$d} = $src->module_magic_number);
}

sub cleanup_for_static {

    return unless $STATIC;

    for (@xs_mod_snames) {
        rename "${_}/${_}.xs.disabled", "${_}/${_}.xs";
    }
}

sub setup_for_static {

    my $d = "$APACHE_SRC/modules/perl";
    my $mf = "$APACHE_SRC/modules/perl/Makefile";
    my @static_src = ();

    unless ($USE_APACI) {
        iedit $mf, "s/(PERL_STATIC_EXTS) =.*/\$1 = $PERL_STATIC_EXTS/"
            if $PERL_STATIC_EXTS;
    }
    return unless $STATIC;

    cp "Apache/typemap", $d;

    for (@xs_mod_snames) {
        rename "${_}/${_}.xs", "${_}/${_}.xs.disabled" if -e "${_}/${_}.xs";
        push @static_src, "$_.c";
    }

=pod
    my @xs_names = ();
    my @xs_files = ();
    my $dir = "src/modules/perl";
    my $dh = DirHandle->new($dir) or die;

    for my $file ($dh->read) {
	next unless $file =~ /\.xs$/;
	push @xs_names, module_name_from_xs("$dir/$file");
	push @xs_files, $file;
	unless ($mani_src{"$dir/$file"}) {
	    cp "$dir/$file", $d;
	    print "Adding module `$xs_names[-1]' to httpd\n";
	}
    }
    #print "XS_NAMES=@xs_names\n";
    #print "XS_FILES=@xs_files\n";

    #XXX think about this some more
    iedit $mf, "s/^#STATIC_SRC.*/STATIC_SRC = @xs_files/";
    iedit $mf, "s/^#STATIC_EXTS.*/STATIC_EXTS = @xs_names/";

=cut

    unless ($USE_APACI) {
        #XXX: ho,hum, need to generate the whole damn thing 
        #instead of all these frigging iedits.
        if ($DYNAMIC) {
        }
        else {
            iedit $mf, "s/^#STATIC_SRC.*/STATIC_SRC = @static_src/";
            iedit $mf, "s/^#STATIC_EXTS.*/STATIC_EXTS = @xs_modules/";
            iedit $mf, "s/^#STATIC_/STATIC_/";
        }

        #bloody hell, make sucks and so does this.
        #this has only cause a few people pain, enough.
        iedit $mf, "s/ \Q\$(STATIC_SRC)\E/ @static_src/";
    }
}

sub module_name_from_xs {
    my $file = shift;

    my $fh = FileHandle->new($file) or
        die "can't open file $file $!";
    my ($module, $package, $prefix, %seen);
    while (<$fh>) {
        if (($module, $package, $prefix) =
            /^MODULE\s*=\s*([\w:]+)(?:\s+PACKAGE\s*=\s*([\w:]+))?(?:\s+PREFIX\s*=\s*(\S+))?\s*$/)
            {
                $seen{$module}++;
            }
    }
    if (keys %seen > 1) {
        warn "$module name guess might be incorrect";
    }

    return (keys %seen)[0];
}

sub asrc {
    my $d = shift;

    my $file = shift || "httpd.h";
    return $d if -e "$d/$file";
    return "$d/include" if -e "$d/include/$file";
    return "$d/main" if -e "$d/main/$file";
    return undef;
}

sub conf_append {

    local *CFG;
    open CFG, ">>t/conf/httpd.conf" or die "open httpd.conf $!";
    print CFG join "\n", @_, "";
    close CFG;

}

sub edit_extra_cflags {
    my ($cfg) = @_;

    my $fh = IO::File->new($cfg) or die "open $cfg $!";
    my $repl = "";
    my @file = ();
    my $ccopts = ccopts();
    my $dssv = "-DSERVER_SUBVERSION";
    my $ssv = qq($dssv=\\"mod_perl/$VERSION\\" );

    my $inc = " $ccopts -I. -I../.. -DUSE_PERL_SSI" if $PERL_SSI;
    $inc .= " -DAPACHE_SSL" if is_ssl() and $PERL_SSI;
    $inc .= $SSL_INCLUDE if $SSL_INCLUDE;
    $inc .= " -DSTRONGHOLD" if is_ssl() =~ /stronghold/i;
    $inc .= " $PERL_EXTRA_CFLAGS" if $PERL_EXTRA_CFLAGS;
    $inc .= " -DMOD_PERL";

    while (<$fh>) {
        push @file, $_;
        next unless /EXTRA_CFLAGS\s*=/;
        next if /mod_perl/; 
        next if /^#/;
        chomp;

        $repl = $_;

        my $backwhack = "";
        if ($repl =~ s/(\\)\s*$//) {
            $backwhack = $1;
        }
        my $mmn = magic_number($APACHE_SRC);
        if ($mmn >= 19980507) {
            $ADD_VERSION = 0;
        }
        if ($ADD_VERSION) {
            if (/$dssv=/) {
                $repl =~ 
                    s{
                      $dssv\s*=\s*(.?)['"](.*?)(.?)["']
                  }[
                    qq($dssv="$1"$2 mod_perl/$VERSION$3"")
                   ]ex;
            }
            else {
                $repl .= " $ssv";
            }
        }

        $file[-1] = "$repl $inc $backwhack\n";
    }
    close $fh;

    if ($repl) {
        $fh = IO::File->new(">$cfg") or die "open $cfg $!";
        print $fh @file;
        close $fh;
    }
}

sub conf_fixup {
    my($mf, $cfg) = @_;

    return if $USE_APACI;

    my $mmn    = magic_number($APACHE_SRC);
    #source re-org
    my $sro = 1 if $mmn >= 19970825;

    edit_extra_cflags($cfg);
    $PERL_STATIC_EXTS ||= "";
    $libperl ||= "";
    my $ldopts = "`$^X $PWD/src/modules/perl/ldopts $PERL_STATIC_EXTS $libperl`";
    iedit $cfg,
        q{next unless /EXTRA_LIBS\s*=/;}.
            q{next if /perl/; chomp;}.
                qq{\$_ .= q| $ldopts\n|;};

    for (split ",", $ADD_MODULE) {
        add_module($cfg,$_);
    }

    if (is_ssl() =~ /stronghold/i) {
        if ($do_link_swap) {
            warn "swapping link order in $mf for Stronghold\n";
            my $repl = quotemeta('$(REGLIB) $(LIBS)');
            iedit $mf, "s:\Q\$(LIBS) \$(REGLIB)\E:$repl:;";

            #XXX hack
            $repl = quotemeta('CFLAGS=$(CFLAGS)');
            iedit $mf, qq(s:\Q\"CFLAGS=\$(CFLAGS)"\E:'$repl':;); #"
        }
        my $repl = q{AUX_CFLAGS='\$(CFLAGS)'};
        iedit $mf, qq{s/AUX_CFLAGS="..CFLAGS."/$repl/};
    }

    {
        my $repl = q{CC='\$(CC)'};
        iedit $mf, qq{s/CC=..CC. /$repl /};
    }
    open (CONF, $cfg) || die "Can't open $cfg: $!";
    while (<CONF>) {
        $seen_modperl++ if 
            /^Module\s+perl_module/i || 
                /^AddModule\s+.*libperl/;
    }
    close CONF;
    unless ($seen_modperl) {
        print "Appending mod_perl to $conf\n";
        open(CONF, ">>$cfg") || die "Can't open $cfg: $!";
        my $line;
        $line = $sro ? "AddModule modules/perl/libperl.a" :
            "Module perl_module         modules/perl/libperl.a";
        print CONF <<EOT;
		
# Embed a perl interpreter
$line


EOT
        close CONF;
    }
    else {
        print "mod_perl already present in $conf\n";
    }
}

sub has_module {
    my($cfg, $name) = @_;

    local *IN;
    open IN, $cfg or die "Can't open $cfg $!\n";
    while (<IN>) {
        if (/^\\w{0,3}Module\\s+.*$name\.[oa]/i) {
            close IN;
            #	    print STDERR "has module $name\n";
            return 1;
        }
    }

    return 0;
}

sub add_module {
    my($cfg, $name) = @_;

    iedit $cfg, "s/^#\\s+(\\w{0,3}Module\\s+.*$name\.[oa])/\$1/";
}

sub gen_script {
    my $file = shift;
    my (@lib) = @_;

    local (*IN,*OUT);
    open IN, "$file.PL" or die "Couldn't open $file.PL: $!";
    open OUT, ">$file" or die "Couldn't open $file: $!";

    print OUT "#!$Config{perlpath}\n";

    if (@lib) {
        print OUT "use lib qw(@lib);\n";
    }
    print OUT join '', <IN>;

    close OUT;
    close IN;

    chmod 0755, "$file";
}

sub iedit {
    my $file = shift;

    return if $Is_Win32;

    #print STDERR "-e @_\n";
    system $^X, "-pi~", "-e", "@_", $file;
}

sub win32_setup {

    my $d = "src/modules/perl";
    dirent_kludge($d);
    cp "Apache/typemap", $d;
    chdir $d;
    system "$^X -MExtUtils::Embed -e xsinit -- -std @xs_modules $PERL_STATIC_EXTS";
    my $lib = $Config{privlibexp};
    for (@xs_mod_snames) {    
        system "$^X $lib/ExtUtils/xsubpp -typemap $lib/ExtUtils/typemap $_.xs > $_.c";
    }
    chdir "../../../";

    open (F, '>t/docs/init.pl') 
        or die "Cannot open t/docs/init.pl: $!";
    print F <<"END";
#!perl
\$Apache::Server::CWD = '$PWD';

END
    close F;
}

sub dirent_kludge {
    my $d = shift;

    local *FH;
    open FH, ">$d/dirent.h" or die "can't write $d/dirent.h $!";
    print FH <<EOF;
/* major kludge to workaround confilct(s) between perl's dirent.h apache's readdir.h */

#ifdef WIN32

#define _INC_DIRENT
#define DIR void

#endif

EOF
    close FH;
}

sub write_version_h {
    my $d = shift;

    unlink "$d/mod_perl_version.h";
    my $pv = perl_version();
    local *FH;
    open FH, ">$d/mod_perl_version.h" or die "can't write $d/mod_perl_version.h $!";
    print FH <<EOF;
#define MOD_PERL_STRING_VERSION "mod_perl/$VERSION"
#define PERLV $pv
EOF
    close FH;
}

sub write_my_config {
    my $src = shift;

    # preparing and writing Configuration to Apache::MyConfig
    my %my_config = %callback_hooks;
    my @other_hooks = qw(
                         APACHE_SRC SSL_BASE APXS PERL_USELARGEFILES
                         PERL_TRACE PERL_DEBUG APACI_ARGS
                         APACHE_PREFIX DO_HTTPD NO_HTTPD PREP_HTTPD
                         USE_APACI APACHE_HEADER_INSTALL
                         PERL_STATIC_EXTS PERL_SSI PERL_SECTIONS USE_APXS WITH_APXS
                        );
    {
        no strict 'refs';
        for (@other_hooks) {
            $my_config{$_} = ${$_};
        }
    }

    if ($win32_auto) {
        for (qw(APACHE_INC APACHE_LIB MODPERL_INC MODPERL_LIB)) {
            $my_config{$_} = $win32_path{$_};
        }
        $my_config{APACHE_SRC} = $APACHE_SRC;
    }

    #need this alias for Apache::src backwards compat
    $my_config{'Apache_Src'} = $my_config{'APACHE_SRC'};
    $my_config{'APXS'} = delete $my_config{'WITH_APXS'};

    my $my_config_dump = join ",\n",
        map {
            qq{'$_' => } .
                ($my_config{$_} =~ /^\d+$/ ? $my_config{$_} : qq{'$my_config{$_}'})
            }
            sort keys %my_config;

    local *FH;
    open FH, '>lib/Apache/MyConfig.pm'  ||
        die "Can't open lib/Apache/MyConfig.pm: $!";
    print FH <<EOT;
#
# Configuration for mod_perl and Apache::...
#
package Apache::MyConfig;

%Setup = (
$my_config_dump
);
1;

__END__

=head1 NAME

Apache::MyConfig - build options access

=head1 SYNOPSIS

 use Apache::MyConfig;
 die unless \$Apache::MyConfig::Setup{PERL_FILE_API};

=head1 DESCRIPTION

B<Apache::MyConfig> module provides access to the various hooks
and features set when mod_perl is built.  This circumvents the
need to set up a live server just to find out if a certain callback
hook is available.

Itterate through \%Apache::MyConfig::Setup to get obtain build
information then see Appendix B of the Eagle book for more detail
on each key.

EOT
    close FH;

}

# obtain the Apache and mod_perl lib and include directories for Win32
sub win32_inc_and_lib {

    my $modperl_src = win32_fix_path(cwd) . '/src';
    $win32_path{MODPERL_INC} = $modperl_src . '/modules/perl';
    $win32_path{MODPERL_LIB} = ($win32_args{DEBUG} == 1) ? 
        $modperl_src . '/modules/win32/Debug' :
            $modperl_src . '/modules/win32/Release';

    unless ( -d $win32_args{APACHE_SRC}) {
        opendir(DIR, '../') or die "Cannot read parent directory: $!\n";
        my @dirs = map {"../$_"}
            grep {/apache/ and -d "../$_"} readdir DIR;
        closedir DIR or die "Cannot close parent directory: $!\n";
        die "Cannot find the apache sources\n" 
            unless ($win32_args{APACHE_SRC} = find_dir(\@dirs, 'apache source'));
    }

    $win32_args{APACHE_SRC} = win32_fix_path($win32_args{APACHE_SRC});
    if (-d "$win32_args{APACHE_SRC}/libexec") {
        $win32_path{APACHE_LIB} = $win32_args{APACHE_SRC} . '/libexec';
        $win32_path{APACHE_INC} = $win32_args{APACHE_SRC} . '/include';
        $win32_args{APACHE_VERS} = httpd_version($win32_path{APACHE_INC}, 1);
    }
    else {
        $win32_args{APACHE_SRC} .= '/src' unless $win32_args{APACHE_SRC} =~ /src$/;
        $win32_path{APACHE_INC} = $win32_args{APACHE_SRC} . '/include';
        $win32_args{APACHE_VERS} = httpd_version($win32_path{APACHE_INC}, 1);
        $win32_path{APACHE_LIB} = ($win32_args{DEBUG} == 1) ? 
            $win32_args{APACHE_SRC} . 
                ($win32_args{APACHE_VERS} < 1315 ? '/CoreD' : '/Debug') :
                    $win32_args{APACHE_SRC} . 
                        ($win32_args{APACHE_VERS} < 1315 ? '/CoreR' : '/Release');
    }

    die "Cannot find ApacheCore.lib under $win32_path{APACHE_LIB}\n"
        unless -f "$win32_path{APACHE_LIB}/ApacheCore.lib";
    die "Cannot find httpd.h under $win32_path{APACHE_INC}\n"
        unless -f "$win32_path{APACHE_INC}/httpd.h";

    if ($win32_args{INSTALL_DLL} ) {
        $win32_args{INSTALL_DLL} =
            win32_fix_path($win32_args{INSTALL_DLL});
        unless ( -d $win32_args{INSTALL_DLL}) {
            my @dirs = grep {-d}
                ('\Program Files\Apache Group\Apache\modules',
                 '\Apache\modules', '\Program Files\Apache\modules');
            $win32_args{INSTALL_DLL} = find_dir(\@dirs, 'Apache/modules');
            if ($win32_args{INSTALL_DLL} and -d $win32_args{INSTALL_DLL}) {
                $win32_args{INSTALL_DLL} =
                    win32_fix_path($win32_args{INSTALL_DLL});
            }
            else {
                print <<'END';

****  The Apache/modules directory was not found.    *******
****      Please install mod_perl.so manually.       *******

END
            }
        }
    }

    if ($win32_args{INSTALL_LIB} ) {
        $win32_args{INSTALL_LIB} = 
            win32_fix_path($win32_args{INSTALL_LIB});
        unless ( -d $win32_args{INSTALL_LIB}) {
            my @dirs = grep {-d}
                ('\Program Files\Apache Group\Apache\libexec', 
                 '\Apache\libexec', '\Program Files\Apache\libexec');
            $win32_args{INSTALL_LIB} = find_dir(\@dirs, 'Apache/libexec');
            if ($win32_args{INSTALL_LIB} and -d $win32_args{INSTALL_LIB}) {
                $win32_args{INSTALL_LIB} = 
                    win32_fix_path($win32_args{INSTALL_LIB});
            }
            else {
                print <<'END';

****  The Apache/libexec directory was not found.    *******
****      Please install mod_perl.lib manually.       *******

END
                                  }
                   }
}
}

# fix mod_perl.dsp with the perl and apache inc and lib directories
sub win32_fix_dsp {

    my $amp = 'src/modules/win32';
    my $dsp = 'mod_perl.dsp';
    unless ( -f "$amp/$dsp.orig") {
        rename("$amp/$dsp", "$amp/$dsp.orig")
            or die "Couldn't rename $amp/$dsp: $!\n";
    }

    my $perl_inc = win32_fix_path_dsp("$Config{archlibexp}/CORE");

    open OLDDSP, "$amp/$dsp.orig"
        or die "Couldn't read $amp/$dsp.orig: $!\n";
    open NEWDSP, ">$amp/$dsp"
        or die "Couldn't create $amp/$dsp: $!\n";
    while (<OLDDSP>) {
        if (/^SOURCE=.*ApacheCore\.lib/) {
            printf NEWDSP "SOURCE=%s\n", 
                win32_fix_path_dsp("$win32_path{APACHE_LIB}/ApacheCore.lib");
        }
        elsif (/^SOURCE=.*perl(56)?\.lib/) {
            print NEWDSP qq{SOURCE=$perl_inc\\$Config{libperl}\n};
        }
        elsif (/ADD CPP/) {
            my $apache_inc = win32_fix_path_dsp($win32_path{APACHE_INC});
            s!/I "\\Perl\\lib\\CORE"!/I "$apache_inc" /I "$apache_inc/../os/win32" /I "$perl_inc"!;
            s!(/D "WIN32")!$1 /D "EAPI" ! if $win32_args{EAPI}; 
            print NEWDSP $_;
        }
        else {
            print NEWDSP $_;
        }	
    }

    close OLDDSP;
    close NEWDSP;

    return;
}

# find a directory of type $type, given some possible $dirs
sub find_dir {
        my ($dirs, $type) = @_;

        my $j = 0;
        my $src;
        while (1) {
            $src = @$dirs > 0 ? $dirs->[$j] : '';
            $src = prompt("\nWhere is your $type directory? (q to quit)", $src);
            return undef if $src eq 'q';
            return $src if -d $src;
            print qq{'$src': no such directory\n};
            $j = ($j == @$dirs-1) ? 0 : $j + 1;
        }
    }

# fix a path for Win32 Makefile
sub win32_fix_path {
    my $path = shift;

    $path = File::Spec->rel2abs($path) if not File::Spec->file_name_is_absolute($path);
    $path = Win32::GetShortPathName($path) if $path =~ / /;
    $path =~ tr!\\!/!;
    $path =~ s!/$!!;
    return $path;
}

# fix a path for mod_perl.dsp
sub win32_fix_path_dsp {
    local $_ = shift;

    tr!/!\\!;

    return $_;
}

#in version 1.2505 of Embed.pm we could just import these instead of using ``,
#but it might require lots of people to upgrade

sub ccopts {

    unless ($Embed::ccopts) {
        $Embed::ccopts = "$Config{ccflags} -I$Config{archlibexp}/CORE";
        if ($USE_THREADS) {
            $Embed::ccopts .= " -DPERL_THREADS";
        }
    }

    $Embed::ccopts;
}

sub ldopts {

    $Embed::ldopts ||= `$^X -MExtUtils::Embed -e ldopts`;
    if ($^O eq "aix") {
        $Embed::ldopts =~ s,(-bE:)(perl\.exp),$1$Config{archlibexp}/$2,;
    }
    $Embed::ldopts;
}

sub perl_version {

    my $v = "$]";
    $v =~ s/\.//g;
    $v .= "0" while length($v) < 6;

    $v;
}

#for linking third-party xs modules static built w/ MakeMaker's: 'make static' 
#must have when the xs module is compiled with profiling `-pg -a' flags
sub add_static_ar {

    $PERL_STATIC_AR ||= "";
    my $cur = $APACHE_SRC =~ /^../ ? "$PWD/" : "";

    for (qw(blib/arch/auto arch/auto)) {
        last if -d ($ar_dir = "$APACHE_SRC/modules/perl/$_");
        $ar_dir = "";
    }

    return unless -d $ar_dir;

    finddepth(
              sub {
                  return unless /^[A-Z]\w+\.a$/;
                  (my $rel = $File::Find::dir) =~ s:$APACHE_SRC/?::;
                  (my $mod = $rel) =~ s:.*auto/::;
                  $mod =~ s,/,::,;
                  print "linking static $mod => $rel/$_\n";
                  $PERL_STATIC_AR .= $cur . "$File::Find::dir/$_ ";
                  $PERL_STATIC_EXTS .= "$mod ";
              }, $ar_dir
             );
}

sub APACI::init {

    return undef if $Is_Win32;
    my $lib_cfg;
    if ($USE_APXS) {
        $lib_cfg = "apaci/mod_perl.config";
        chmod 0644, $lib_cfg;
    }
    elsif ($USE_APACI) {
        $lib_cfg = "$APACHE_SRC/modules/perl/mod_perl.config";
    }
    else {
        return undef;
    }

    unless (File::Compare::compare($lib_cfg,"apaci/mod_perl.config") == 0) {
        #warn "mod_perl.config already edited\n";
        #return undef;
    }

    my $apaci_cfg = FileHandle->new(">$lib_cfg") or
        die "can't open $lib_cfg $!";

    my @static_src = ();

    for (@xs_mod_snames) {
        push @static_src, "$_.c";
    }

    add_static_ar();

    my $static_targets = "";
    $static_targets = <<EOF unless $DYNAMIC;
PERL_STATIC_EXTS = @xs_modules $PERL_STATIC_EXTS
PERL_STATIC_SRCS = @static_src
EOF

    $static_targets .= "PERL_STATIC_AR = $PERL_STATIC_AR\n" if $PERL_STATIC_AR;

    print $apaci_cfg <<EOF;
##
##  mod_perl.config -- mod_perl shared configuration file
##

#   mod_perl version
MOD_PERL_VERSION = $VERSION

#   Perl interpreter to use 
PERL = $^X
LIBPERL = $LIBPERL

$static_targets

EOF

    print $apaci_cfg <<EOF if defined $MOD_PERL_PREFIX;

# mod_perl installation prefix
MOD_PERL_PREFIX = $MOD_PERL_PREFIX

EOF

    for (qw(PERL_SECTIONS PERL_SSI PERL_TRACE)) {
        my $yes_no = $$_ ? "yes" : "no";
        print $apaci_cfg "$_ = $yes_no\n";
    }

    $yes_no = 'no';
    $yes_no = 'yes' if $USE_THREADS;
    print $apaci_cfg "PERL_THREADS = $yes_no\n";

    return $apaci_cfg;
}

sub phat_warn {
    my ($msg, $abort) = @_;

    my $level = $abort ? "ERROR" : "WARNING";
    warn <<EOF;
************* $level *************

  $msg

************* $level *************
EOF
    if ($abort) {
        exit 1;
    }
    else {
        sleep 5;
    }
}

sub system_sanity_check {

    return if $Is_Win32;

    my $ccflags = $Config{'ccflags'};
    for (split /\s+/, $ccflags) {
        next unless s/^-I//;
        my $header = "$_/ap_mmn.h";
        if (-e $header) {
            phat_warn(<<EOF);
Apache headers found in unexpected location: ``$_'', suggestions:
   *) Remove via ``rpm -e apache''
   *) Remove by hand
   *) Complain to your os vendor about their poor layout choice
   *) Complain to your sysadmin about their poor layout choice
EOF
        }
    }

    my $ld = basename $Config{ld};

    if ($^O eq 'hpux' and ($USE_DSO or $USE_APXS) and $ld eq 'ld') {
        unless ($ccflags =~ /\+z/i) {
            my $switch = $] >= 5.006 ? 'A' : 'D';
            phat_warn(<<EOF);
mod_perl is unlikely to link with your libperl, suggestions:
    *) Rebuild Perl with Configure -${switch}ccflags=+Z ...
    *) Build mod_perl static rather than DSO
EOF
        }
    }

    gdbm_check();
    malloc_check();
    uselargefiles_check();
    dynaloader_check();
    shrplib_check();

    if ($USE_APXS and $Config{libs} =~ /($thrlib)/) {
        my $lib = $1;
        phat_warn(<<EOF);
Your Perl is linked with $lib, make sure that your httpd is built with LIBS=$lib
EOF
    }
}

sub gdbm_check {

    if ($Config{libs} =~ /gdbm/) {
        require DynaLoader;
        require AutoLoader; #eek
        my $found = 0;
        my @path = split /\s+/, $Config{libpth};

        for (@path) {
            last if $found = DynaLoader::dl_findfile($_, "-lgdbm");
        }

        unless ($found) {
            my @maybe = ();
            for (@path) {
                push @maybe, grep { ! -l $_ } <$_/libgdbm.*>;
            }

            my $suggest = @maybe ? 
                "You could just symlink it to $maybe[0]" :
                    "You might need to install Perl from source";
            phat_warn(<<EOF);
Your Perl is configured to link against libgdbm, 
  but libgdbm.so was not found.
  $suggest
EOF
        }
    }
}

sub uselargefiles_check {

    return unless $] >= 5.006 and $Config{uselargefiles}
        and $PERL_USELARGEFILES and $USE_APXS;

    local $Apache::src::APXS = $WITH_APXS;
    my $cflags = Apache::src->new->apxs('-q' => 'CFLAGS') || '';
    return if $cflags =~ /LARGEFILE/;

    $PERL_USELARGEFILES=0; #just do it since
    return; #nobody seems to listen to the warning below

    phat_warn(<<EOF);
Your Perl is uselargefiles enabled, but Apache is not, suggestions:
    *) Rebuild mod_perl with Makefile.PL PERL_USELARGEFILES=0
    *) Rebuild Apache with CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
    *) Rebuild Perl with Configure -Uuselargefiles
    *) Let mod_perl build Apache (USE_DSO=1 instead of USE_APXS=1)
EOF
}

sub malloc_check {
    return unless $USE_DSO or $USE_APXS;
    return unless $Config{'usemymalloc'} eq 'y';

    my $abort = $^O eq 'solaris';

    my $bincompat = $Config{bincompat5005} and 
                    $Config{bincompat5005} eq 'define';

    if ($] < 5.006) {
        phat_warn(<<EOF, $abort);
Your current configuration will most likely trigger core dumps, suggestions:
   *) Do not configure mod_perl as a DSO
   *) Upgrade your Perl version to 5.6.0 or higher (w/ -Ubincompat5005)
   *) Configure Perl with -Uusemymalloc (not recommended for performance)
EOF
     }
     elsif ($bincompat) {
             phat_warn(<<EOF, $abort);
Your current configuration will most likely trigger core dumps, suggestions:
   *) Do not configure mod_perl as a DSO
   *) Rebuild Perl without malloc pollution (Configure -Ubincompat5005)
EOF
    }
}

sub dynaloader_check {

    return unless $^O eq 'aix' and $] <= 5.00503 and ($USE_DSO or $USE_APXS);
    phat_warn(<<EOF);
Please make sure that you apply the following patch to the perl
distribution before you install mod_perl, without this patch you will
not be able load any xs modules.
EOF

    warn <<EOF;
--- perl5.005_03/ext/DynaLoader/dl_aix.xs.orig	Fri Mar  3 17:00:58 2000
+++ perl5.005_03/ext/DynaLoader/dl_aix.xs	Sun Apr  2 13:37:05 2000
@@ -74,8 +74,8 @@
 } Module, *ModulePtr;
 
 /*
- * We keep a list of all loaded modules to be able to call the fini
- * handlers at atexit() time.
+ * We keep a list of all loaded modules to be able to reference count
+ * duplicate dlopen's.
  */
 static ModulePtr modList;
 
@@ -88,7 +88,6 @@
 
 static void caterr(char *);
 static int readExports(ModulePtr);
-static void terminate(void);
 static void *findMain(void);
 
 static char *strerror_failed   = "(strerror failed)";
@@ -165,7 +164,6 @@
	if (!mainModule) {
		if ((mainModule = findMain()) == NULL)
			return NULL;
-		atexit(terminate);
	}
	/*
	 * Scan the list of modules if have the module already loaded.
@@ -222,7 +220,16 @@
	mp->refCnt = 1;
	mp->next = modList;
	modList = mp;
-	if (loadbind(0, mainModule, mp->entry) == -1) {
+	/*
+	 * Assume anonymous exports come from the module this dlopen
+	 * is linked into, that holds true as long as dlopen and all
+	 * of the perl core are in the same shared object. Also bind
+	 * against the main part, in the case a perl is not the main
+	 * part, e.g mod_perl as DSO in Apache so perl modules can
+	 * also reference Apache symbols.
+	 */
+	if (loadbind(0, (void *)dlopen, mp->entry) == -1 ||
+	    loadbind(0, mainModule, mp->entry) == -1) {
		dlclose(mp);
		errvalid++;
		strcpy(errbuf, "loadbind: ");
@@ -336,12 +343,6 @@
	safefree(mp->name);
	safefree(mp);
	return result;
-}
-
-static void terminate(void)
-{
-	while (modList)
-		dlclose(modList);
 }
 
 /* Added by Wayne Scott 

EOF
}

sub shrplib_check {

    return unless $Config{'useshrplib'} and
        $Config{'useshrplib'} eq 'define';

    my $libperl = $Config{'libperl'} || 'libperl.so';

    for my $dir (qw(/lib /usr/lib /usr/local/lib)) {
        next unless -e "$dir/$libperl";

        my $coredir = "$Config{'archlibexp'}/CORE";
        my $corelib = "$coredir/$libperl";

        phat_warn(<<EOF);
$dir/$libperl might override
$corelib

This may cause build or runtime errors with mod_perl.
Consider removing $dir/$libperl, it should not be there.

If your vendor has installed $libperl there, complain to them and install
Perl from source if needed.

$libperl should only exist in Perl version/arch directories, for example:
$coredir
EOF
    }
}
