#!/usr/bin/perl -w -I/opt/eprints3/perl_lib ###################################################################### # # This file is part of GNU EPrints 2. # # Copyright (c) 2000-2004 University of Southampton, UK. SO17 1BJ. # # EPrints 2 is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # EPrints 2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with EPrints 2; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # ###################################################################### =pod =head1 NAME B<generate_apacheconf> - Create the apache config files needed for EPrints =head1 SYNOPSIS B<generate_apacheconf> [B<options>] =head1 DESCRIPTION This script generates the apache config files which will be used by EPrints. In the simple case all you need to do is run this script then add a line to your main apache configuration file - often, but not always, B</usr/local/apache/conf/httpd.conf> Include /opt/eprints3/cfg/apache.conf Or elsewhere if you installed EPrints somewhere other than /opt/eprints3. This file then uses the "Include" directive to include all relevant apache config files from this EPrints installation. By default the virtualhost directives are VirtualHost * But the * can be changed to something different by editing the C<virtualhost> option in SystemSettings.pm =head1 ARGUMENTS =over 8 =back =head1 OPTIONS =over 8 =item B<--help> Print a brief help message and exit. =item B<--man> Print the full manual page and then exit. =item B<--quiet> Be vewwy vewwy quiet. This option will supress all output unless an error occurs. =item B<--verbose> Explain in detail what is going on. May be repeated for greater effect. =item B<--version> Output version information and exit. =back =head1 FILES =over 4 =item B<EPRINTS/cfg/apache.conf> This file is not updated if it already exists, so you can add system-wide apache configuration directives here. By default it just includes the two other system wide files: auto-apache-includes.conf and auto-apache.conf =item B<EPRINTS/cfg/auto-apache-includes.conf> This file is updated with Include lines to each of the repository specific apache config files. This file should not be edited by hand, =item B<EPRINTS/cfg/auto-apache.conf> This file contains the system wide apache directives required by EPrints. This file should not be edited by hand. =item B<EPRINTS/archives/ARCHIVEDIR/cfg/apache.conf> This file is not updated if it already exists, so you can add repository-specific apache configuration directives here. By default it just includes the automatically generated repository specific file: auto-apache.conf =item B<EPRINTS/archives/ARCHIVEDIR/var/auto-apache.conf> This file contains all the configuration directives needed for an repository. This is where the bulk of the configuration appears, the clever stuff, if you will. This file should not be edited by hand. =item B<EPRINTS/archives/ARCHIVEDIR/var/auto-secure.conf> Only created if the repository has a securehost configured. This file contains all the configuration options that need to be included into the secure server virtualhost. =item B<EPRINTS/archives/ARCHIVEDIR/cfg/apachevhost.conf> This file is not updated if it already exists, it is included into the virutalhost in auto-apache.conf so that you can a couple of additional directives if you need to. For example, redirects or additional log directives. =back =head1 AUTHOR This is part of this EPrints 3 system. EPrints 3 is developed by Christopher Gutteridge. =head1 VERSION EPrints Version: 3.0 =head1 CONTACT For more information goto B<http://www.eprints.org/> which give information on mailing lists and the like. Chris Gutteridge may be contacted at B<support@eprints.org> Should you need a real world address for some reason, EPrints can be contacted in the real world at EPrints c/o Christopher Gutteridge Department of Electronics and Computer Science University of Southampton SO17 1BJ United Kingdom =head1 COPYRIGHT This file is part of GNU EPrints 2. Copyright (c) 2000-2004 University of Southampton, UK. SO17 1BJ. EPrints 2 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. EPrints 2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with EPrints 2; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA =cut use EPrints; use strict; use Getopt::Long; use Pod::Usage; my $version = 0; my $verbose = 0; my $quiet = 0; my $help = 0; my $man = 0; GetOptions( 'help|?' => \$help, 'man' => \$man, 'version' => \$version, 'verbose+' => \$verbose, 'silent' => \$quiet, 'quiet' => \$quiet ) || pod2usage( 2 ); EPrints::Utils::cmd_version( "generate_apacheconf" ) if $version; pod2usage( 1 ) if $help; pod2usage( -exitstatus => 0, -verbose => 2 ) if $man; pod2usage( 2 ) if( scalar @ARGV != 0 ); our $noise = 1; $noise = 0 if( $quiet ); $noise = 1+$verbose if( $verbose ); #cjg Write a more simple conf if only one language involved? # Set STDOUT to auto flush (without needing a \n) $|=1; # Load up the repositories my %reps = (); foreach my $repository_id ( EPrints::Config::get_repository_ids() ) { $reps{$repository_id} = new EPrints::Repository( $repository_id, 1 ); exit( 1 ) unless( defined $reps{$repository_id} ); } my $av = $EPrints::SystemSettings::conf->{apache}; $av = "1" unless defined $av; my $site_sysfile = EPrints::Config::get( "var_path" )."/auto-apache.conf"; my $site_incfile = EPrints::Config::get( "var_path" )."/auto-apache-includes.conf"; my $site_userfile = EPrints::Config::get( "cfg_path" )."/apache.conf"; print "Creating system wide apache conf files.\n" if( $noise >= 1 ); # Clean up old auto files. Especially old secure ones opendir( my $dir, EPrints::Config::get( "var_path" ) ); while( my $file = readdir( $dir ) ) { if( $file =~ m/^auto-.*\.conf$/ ) { my $fn = EPrints::Config::get( "var_path" ).'/'.$file; unlink( $fn ); } } unless( -e $site_userfile ) { print "Creating $site_userfile\n" if( $noise >= 2 ); open( CONF, ">$site_userfile" ) || die "Can't write to $site_userfile"; print CONF <<END; # # apache.conf include file for EPrints # # If this file exists then it will not be over written by # # Put your own extra directives for this site here # # Comment out the "Include" lines if you don't want to use the # autogenerated config for this repository. # # Include list of 'Include's for each repository Include $site_incfile # Include autogenerate apache.conf elements Include $site_sysfile END close CONF; } else { print "$site_userfile already exists.\n" if( $noise >= 2 ); } my $virtualhost = EPrints::Config::get( "virtualhost" ); if( !EPrints::Utils::is_set( $virtualhost ) ) { $virtualhost = '*'; } print "Creating $site_sysfile\n" if( $noise >= 2 ); my $startupfile = EPrints::Config::get( "bin_path" )."/startup.pl"; open( CONF, ">$site_sysfile" ) || die "Can't write to $site_sysfile"; print CONF <<END; # # auto-apache.conf include file for EPrints # # DO NOT EDIT, this file is created by bin/generate_apacheconf # and may be overwritten. To modify, change the repository configuration # and re-run: bin/generate_apacheconf # # Load the perl modules & repository configurations PerlSetEnv EPRINTS_APACHE $av PerlRequire $startupfile END my %portlist = (); foreach my $repository_id ( keys %reps ) { $portlist{$reps{$repository_id}->get_conf( 'port' )} = 1; } foreach my $port ( keys %portlist ) { print CONF "NameVirtualHost $virtualhost:$port\n"; } print CONF "\n"; if( $av eq "2" ) { # apache 2 print CONF <<END; # Makes the request object accessable for other objects # (apache 2.0 only) PerlOptions +GlobalRequest END } close CONF; ######################################## print "Creating $site_incfile\n" if( $noise >= 2 ); open( CONF, ">$site_incfile" ) || die "Can't write to $site_incfile"; print CONF <<END; # # auto-apache-includes.conf include file for EPrints # # DO NOT EDIT, this file is created by bin/generate_apacheconf # and may be overwritten. To modify, change the repository configuration # and re-run: bin/generate_apacheconf # # List of files to include for repository specific config... END foreach my $repository_id ( keys %reps ) { my $repository_inc = $reps{$repository_id}->get_conf( "archiveroot" )."/cfg/apache.conf"; print CONF <<END; # $repository_id Include $repository_inc END } close CONF; ########################################F#N#O#R#D######## # # Write apache conf files for each repository # ########################################F#N#O#R#D######## my $secureconfigs = {}; foreach my $repository_id ( keys %reps ) { my $repository = $reps{$repository_id}; exit( 1 ) unless( defined $repository ); my $sysfile = $repository->get_conf( "variables_path" )."/auto-apache.conf"; my $userfile = $repository->get_conf( "config_path" )."/apache.conf"; my $vhostfile = $repository->get_conf( "config_path" )."/apachevhost.conf"; my $securefile = $repository->get_conf( "variables_path" )."/auto-secure.conf"; my $id = $repository->get_id(); print "Creating apache conf files for repository $repository_id\n" if( $noise >= 1 ); unless( -e $userfile ) { print "Creating $userfile\n" if( $noise >= 2 ); open( CONF, ">$userfile" ) || die "Can't write to $userfile"; print CONF <<END; # # apache.conf include file for $id # # If this file exists then it will not be over written by # the generate_apacheconf command. # # Put your own extra directives for this site here # # Comment out the "Include" line if you don't want to use the # autogenerated config for this repository. # Include $sysfile END } else { print "$userfile already exists.\n" if( $noise >= 2 ); } unless( -e $vhostfile ) { print "Creating $vhostfile\n" if( $noise >= 2 ); open( CONF, ">$vhostfile" ) || die "Can't write to $vhostfile"; print CONF <<END; # # apachevhost.conf include file for $id # # If this file exists then it will not be over written by # the generate_apacheconf command. # # Directives in this file are interpreted inside the virtualhost # configuration for this repository. # END } else { print "$vhostfile already exists.\n" if( $noise >= 2 ); } my $cgidir = EPrints::Config::get( "cgi_path" ); my $adminemail = $repository->get_conf( "adminemail" ); my $htdocs_path = $repository->get_conf( "htdocs_path" ); my $documents_path = $repository->get_conf( "documents_path" ); my $host = $repository->get_conf( "host" ); my $port = $repository->get_conf( "port" ); my $hostport = $host; if( $port != 80 ) { $hostport.=":$port"; } my $urlpath = $repository->get_conf( "urlpath" ); my $userhome = $repository->get_conf( "userhome" ); my $securehost = $repository->get_conf( "securehost" ); my $securepath = ''; my $archiveroot = $repository->get_conf( "archiveroot" ); if( EPrints::Utils::is_set( $securehost ) ) { $securepath = $repository->get_conf( "securepath" ); } print "Creating $sysfile\n" if( $noise >= 2 ); open( CONF, ">$sysfile" ) || die "Can't write to $sysfile"; print CONF <<END; # # auto-apache.conf include file for $id # # DO NOT EDIT, this file is created by bin/generate_apacheconf # and may be overwritten. To modify, change the repository configuration # and re-run: bin/generate_apacheconf $id # END my $aliasinfo; my $aliases = ""; foreach $aliasinfo ( @{$repository->get_conf( "aliases" )} ) { if( $aliasinfo->{redirect} ) { my $vname = $aliasinfo->{name}; print CONF <<END; # Redirect to the correct hostname <VirtualHost $virtualhost:$port> ServerName $vname Redirect / http://$hostport/ </VirtualHost> END } else { $aliases.=" ServerAlias ".$aliasinfo->{name}."\n"; } } print CONF <<END; # The main virtual host for this repository <VirtualHost $virtualhost:$port> ServerName $host $aliases ServerAdmin $adminemail # Include this here, so that it's rules come first. Include $vhostfile END # If we want to use the non-perl CGI script mimetex.cgi we need to # insert the script alias here. if( $repository->get_conf( "use_mimetex" ) ) { if( !defined $EPrints::SystemSettings::conf->{executables}->{mimetex} ) { EPrints::abort( "use_mimetex is set to true but\n\$EPrints::SystemSettings::conf->{executables}->{mimetex}\nis not set." ); } if( !-e $EPrints::SystemSettings::conf->{executables}->{mimetex} ) { EPrints::abort( "use_mimetex is set to true but\n\$EPrints::SystemSettings::conf->{executables}->{mimetex}\nis set to a non existant file." ); } print CONF ' ScriptAlias '.$urlpath.'/cgi/mimetex.cgi '.$EPrints::SystemSettings::conf->{executables}->{mimetex}."\n\n"; } print CONF <<END; Alias $urlpath/thumbnails/ $archiveroot/thumbnails/ Alias $urlpath/cgi $cgidir Alias $urlpath/ $htdocs_path/ <Location "$urlpath"> ErrorDocument 401 $urlpath/error401.html ErrorDocument 404 $urlpath/cgi/handle_404 PerlSetVar EPrints_ArchiveID $repository_id Redirect /perl/ http://$hostport/cgi/ PerlSetVar EPrints_Dir_SecuredCGI $cgidir/users PerlSetVar EPrints_Dir_Documents $documents_path Order allow,deny Allow from all END # EPrints log handler (this gets called for all requests, not just # mod_perl) if( $av == 2 && $repository->get_conf( "loghandler" ) && $repository->get_conf( "loghandler" )->{ "enable" } ) { # apache 2 print CONF <<END; PerlLogHandler EPrints::Apache::LogHandler END } print CONF <<END; </Location> # Note that PerlTransHandler can't go inside # a "Location" block as it occurs before the # Location is known. PerlTransHandler EPrints::Apache::Rewrite END my @langs = @{$repository->get_conf( "languages" )}; #my $defaultlang = $repository->get_conf( "defaultlanguage" ); # cjg remove this stuff later. # #foreach my $langid ( @langs ) #{ #next if( $langid eq $defaultlang ); #print CONF <<END; #RewriteCond %{HTTP_COOKIE} lang=$langid #RewriteRule ^/(.*)\$ /$langid/\$1 [L] # #END #} # #print CONF <<END; ## Default Language #RewriteRule ^/(.*)\$ /$defaultlang/\$1 [L] # #END if( $repository->get_conf( "vlit" )->{enable} ) { foreach my $langid ( @langs ) { print CONF <<END; <Directory "$htdocs_path/$langid/archive"> SetHandler perl-script PerlHandler EPrints::Apache::VLit::handler </Directory> END } } if( $repository->get_conf( "dynamic_template","enable" ) ) { foreach my $langid ( @langs ) { print CONF <<END; <Directory "$htdocs_path"> SetHandler perl-script PerlResponseHandler EPrints::Apache::Template::handler </Directory> END } } my $registry_module; if( $av eq "1" ) { $registry_module = "Apache::Registry"; } else # apache 2 { $registry_module = "ModPerl::Registry"; } print CONF <<END; <Directory "$htdocs_path"> Order deny,allow Allow from all AddType 'text/html; charset=UTF-8' .html </Directory> <Directory "$documents_path"> AuthName "Documents Area" AuthType "Basic" PerlAuthenHandler EPrints::Apache::Auth::authen_doc PerlAuthzHandler EPrints::Apache::Auth::authz_doc require valid-user </Directory> <Directory "$cgidir"> SetHandler perl-script PerlHandler $registry_module PerlSendHeader Off Options ExecCGI FollowSymLinks </Directory> END my $secureconfig = <<END; <Directory "$cgidir/users"> AuthName "User Area" AuthType "Basic" PerlAuthenHandler EPrints::Apache::Auth::authen PerlAuthzHandler EPrints::Apache::Auth::authz require valid-user SetHandler perl-script PerlHandler $registry_module PerlSendHeader Off Options ExecCGI FollowSymLinks </Directory> <Directory "$cgidir/users/awstats"> PerlSendHeader On </Directory> END unless( EPrints::Utils::is_set( $securehost ) ) { print CONF <<END; $secureconfig </VirtualHost> END close CONF; next; } # This site has an HTTPS component. Redirect sceure stuff there... my $securebase = "https://".$securehost.$securepath; print CONF <<END; Redirect /cgi/users/ $securebase/cgi/users/ Redirect /change_user $securebase/change_user Redirect /cgi/confirm $securebase/cgi/accounts/confirm Redirect /cgi/register $securebase/cgi/accounts/register Redirect /cgi/reset_password $securebase/cgi/accounts/reset_password Redirect /cgi/set_password $securebase/cgi/accounts/set_password </VirtualHost> END close CONF; # Create secure include file # error documents can't change server # need to make secure 401 and 404 pages, I guess. #ErrorDocument 401 $baseurl/error401.html #ErrorDocument 404 $baseurl/cgi/handle_404 open( CONF, ">$securefile" ) || die "Can't write to $securefile"; print CONF <<END; # # auto-secure.conf include file for $id # # DO NOT EDIT, this file is created by bin/generate_apacheconf # and may be overwritten. To modify, change the repository configuration # and re-run: bin/generate_apacheconf $id # This file is intended to be included inside your HTTPS virtualhost # You have to do that yourself. $secureconfig <Location "$securepath"> PerlSetVar EPrints_ArchiveID $repository_id PerlSetVar EPrints_Secure yes END # EPrints log handler (this gets called for all requests, not just # mod_perl) if( $av == 2 && $repository->get_conf( "loghandler" ) && $repository->get_conf( "loghandler" )->{ "enable" } ) { # apache 2 print CONF <<END; PerlLogHandler EPrints::Apache::LogHandler END } print CONF <<END; </Location> <Directory "$cgidir"> SetHandler perl-script PerlHandler $registry_module PerlSendHeader Off Options ExecCGI FollowSymLinks </Directory> PerlTransHandler EPrints::Apache::Rewrite Alias $securepath/cgi/accounts/confirm $cgidir/confirm Alias $securepath/cgi/accounts/register $cgidir/register Alias $securepath/cgi/accounts/reset_password $cgidir/reset_password Alias $securepath/cgi/accounts/set_password $cgidir/set_password Alias $securepath/cgi/users/ $cgidir/users/ Alias $securepath/ $htdocs_path/ ##### END OF CONFIG FOR $id END close CONF; } print "\nDo not forget to stop and restart apache to cause changes to take effect!\n" if( $noise >= 1 ); print "Exiting normally.\n" if( $noise >= 2 ); exit;