package INSTALL::apache; use INSTALL::common; use INSTALL::os; use INSTALL::query; use strict; my $pGlobals = \%INSTALL::global::variables; my $pParameters = \%INSTALL::parameter::variables; my $pOS = \%INSTALL::os::Details; my %CONST_DefaultWebserverMap = ( LINUX => { REDHAT => { webserver_root => "/etc/httpd", webserver_binary_root => "/usr/sbin", webserver_conf => "/etc/httpd/conf/httpd.conf", webserver_start_script => "/etc/rc.d/init.d/httpd start", webserver_stop_script => "/etc/rc.d/init.d/httpd stop" }, SUSE => { webserver_root => "/etc/httpd", webserver_binary_root => "/usr/sbin", webserver_conf => "/etc/httpd/conf/httpd.conf", webserver_start_script => "/etc/rc.d/init.d/httpd start", webserver_stop_script => "/etc/rc.d/init.d/httpd stop" }, SLACKWARE => { webserver_root => "/var/lib/apache", webserver_binary_root => "/var/lib/apache/sbin", webserver_conf => "/var/lib/apache/conf/httpd.conf", # These don't need to be special cased, my apachectl will work # appropriately. # webserver_start_script => "/var/lib/apache/sbin/apachectl start", # webserver_stop_script => "/var/lib/apache/sbin/apachectl stop" }, DEBIAN => { webserver_root => "/etc/apache", webserver_binary_root => "/usr/sbin", webserver_conf => "/etc/apache/conf/httpd.conf", # These don't need to be special cased, my apachectl will work # appropriately. # webserver_start_script => "/var/lib/apache/sbin/apachectl start", # webserver_stop_script => "/var/lib/apache/sbin/apachectl stop" } } ); #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # External functions #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #------------------------------------------------------------------------------ # This method attempts to find an apache server located in the directory # specified. It does this by checking for an httpd.conf file in the conf # subdirectory under this directory. If a configuration file (or files) is # found, they are returned as a list. #------------------------------------------------------------------------------ sub locate_server { ($#_ == 0) || die "Invalid number of arguments."; my ($server_path) = @_; sub isDir { ($#_ == 0) || die "Invalid number of arguments."; my ($dir) = @_; return((-d $dir) && (not -l $dir)); } # Scanning the components dir will find our / other bundle's httpd.conf # template which will flag an error. Ignore any such httpd.conf. if ($server_path =~ m@INSTALL/templates@) { return(); } elsif ($server_path =~ m@var/adm/SuSEconfig/md5@) { return(); } elsif (isDir("$server_path/conf") && -f "$server_path/conf/httpd.conf") { return(INSTALL::common::realpath("$server_path/conf/httpd.conf")); } elsif (-f "$server_path/httpd.conf") { return(INSTALL::common::realpath("$server_path/httpd.conf")); } else { # Make sure we match a subdirectory with the name apache in it, for # completeness. local *ROOT; if (opendir(ROOT,"$server_path")) { my @subfiles = readdir(ROOT); closedir(ROOT); if ("$server_path" eq "/") { # Handle double '/' in configuration files located in the root. $server_path = ""; } foreach (@subfiles) { if ((($_ ne ".") && ($_ ne "..")) && (isDir("$server_path/$_") && /apache/i)) { return(locate_server("$server_path/$_")); } } } return(); } } #------------------------------------------------------------------------------ # Searches the provided paths for all occurrences of an apache binary. Apache # binaries are searched such that secure servers are searched first. #------------------------------------------------------------------------------ { my @apache_server_names = ('httpsd','apachesd','httpd','apache','apached','chilisoft-httpd'); sub locate_apache_binary { my (@paths) = @_; my $result; LOCATE_APACHE_BINARY_BINARY: foreach my $root (@paths) { foreach my $binary (@apache_server_names) { # Begin the guessing game ... my $binary_guess = "$root/$binary"; if (-x $binary_guess) { $result = $binary_guess; last LOCATE_APACHE_BINARY_BINARY; } } } return($result); } } #------------------------------------------------------------------------------ # This method merely discovers as much as it can about the server with the # information pointed to by $pHash, storing this information in the $pHash. #============================================================================== # pHash is guaranteed to contain: # webserver_conf = # webserver_type = apache #------------------------------------------------------------------------------ sub cache_server { ($#_ == 0) || die "Invalid number of arguments to cache_server."; my $pServerStats = shift @_; my $autostart_enabled; # Any note set by cache_server is only valid for one run-through of # cache_server. Reset it. If it needs to be set, it will be set # below. $pServerStats->{webserver_note} = ''; ## Preemptively discover the start / stop scripts, if possible. my $pWebserverMap = $CONST_DefaultWebserverMap{uc($pOS->{os})}; my $pDistMap; if ($pWebserverMap) { $pDistMap = $pWebserverMap->{uc($pOS->{distribution})}; # First, try an exact match using the distribution. If that fails, # try using the distribution flavor, then 'Default', in that order. # If none match, then no known default setup exists for the box this # is being installed on. if (not $pDistMap) { $pDistMap = $pWebserverMap->{uc($pOS->{distribution_flavor})}; } if (not $pDistMap) { $pDistMap = $pWebserverMap->{DEFAULT}; } if ($pDistMap) { if ($pServerStats->{webserver_conf} eq $pDistMap->{webserver_conf}) { if (exists $pDistMap->{webserver_start_script}) { $pServerStats->{webserver_start_script} = $pDistMap->{webserver_start_script}; $pServerStats->{webserver_stop_script} = $pDistMap->{webserver_stop_script}; $autostart_enabled = 1; } # Add the webserver_binary_root for this platform to the head of the list. if ((not exists $pServerStats->{webserver_binary}) && exists $pDistMap->{webserver_binary_root}) { my $result = locate_apache_binary($pDistMap->{webserver_binary_root}); if ($result) { $pServerStats->{webserver_binary} = $result; } } } } } unless (open(CONFIG, "<$pServerStats->{webserver_conf}")) { return(error("Could not open $pServerStats->{webserver_conf}.")); } # This webserver is to be identified as an Apache webserver. $pServerStats->{webserver_name} = 'Apache'; # Is considered bundled if installed in our directory. $pServerStats->{webserver_bundled} = (($pServerStats->{webserver_conf} =~ /^$pGlobals->{asphome}/) ? "yes" : "no"); # Default to no. $pServerStats->{webserver_https} = "no"; my @in_block; my ($SSL_Module,$SSL_KeyFile); while () { if (m@^\s*<([A-Za-z_]+)@) { # Mandrake 8.1 has Port inside a block # (only take !Defined settings) my $block_head = $1; if (!/IfDefine\s+\!/) { # if the line doesn't have "IfDefine !" # then treat this as a block, otherwise # pretend that it is not really a block unshift @in_block, $block_head; } } elsif (@in_block && m@^\s*{webserver_root} = $1; } elsif (/^\s*ServerName\s+(\S+)/) { $pServerStats->{webserver_realhost} = $1; } elsif (/^\s*Port\s+([0-9]+)/) { $pServerStats->{webserver_port} = $1; } } # Always check for SSL. elsif (/^\s*SSLCertificateKeyFile\s+(\S+)/) { $SSL_KeyFile = $1; } elsif (/^\s*LoadModule\s+ssl_module\s+(.*)/) { $SSL_Module = $1; } } # Check to see if the detected SSL module is actually there. If it is # assume that we are running with SSL. if (defined $SSL_Module) { if ($SSL_Module !~ m@^/@) { $SSL_Module = "$pServerStats->{webserver_root}/$SSL_Module"; } if ($SSL_KeyFile !~ m@^/@) { $SSL_KeyFile = "$pServerStats->{webserver_root}/$SSL_KeyFile"; } if (-f $SSL_KeyFile) { local *KEYFILE; my $key_encrypted; my $key_begin; my $key_end; if (open(KEYFILE,"<$SSL_KeyFile")) { foreach() { if (/ENCRYPTED/) { $key_encrypted = 1; last; } # bug 3751, does it have something like # "BEGIN RSA PRIVATE KEY" and "END RSA PRIVATE KEY"? # if not, it's not a valid key and we should not # be marking SSL as active. if (/BEGIN.*KEY/) { $key_begin = 1; } if (/END.*KEY/) { $key_end = 1; } } close(KEYFILE); } if ($key_encrypted) { my @message = ("Setup has detected SSL in your web server. Unfortunately, it cannot", "deal with encrypted key files, as they require user interaction", "upon Apache startup. As such, encryption needs to be removed before", "SSL will be enabled for your ASP server. Refer to your OpenSSL ", "documentation for information about removing PassKey encryption. It", "is __HIGHLY RECOMMENDED__ that you do __NOT__ install to this web ", "server, as it will be without its SSL protection."); if ($pServerStats->{webserver_note}) { $pServerStats->{webserver_note} .= "\n"; } $pServerStats->{webserver_note} .= join("\n",@message); # Should this be logged as an error (I doubt it)? # error_log(@message); } # bug 3751... on SuSE they ship with a bogus server.key # this is a big hint that SSL is not enabled because if # it were, apache wouldn't start (with the the bogus key) elsif (-f $SSL_Module && ($key_begin && $key_end)) { $pServerStats->{webserver_https} = 'yes'; } } } close(CONFIG); # Remove any "" encapsulation. foreach (keys %{$pServerStats}) { $pServerStats->{$_} =~ s/\"([^\"]*)\"/$1/; } if (exists $pParameters->{webserver_binary}) { if (-x $pParameters->{webserver_binary}) { my $valid_apache = `$pParameters->{webserver_binary} -v`; if ($valid_apache !~ /apache/i) { note("The specified webserver_binary=$pParameters->{webserver_binary} option", "specifies a binary which does not appear to be an Apache binary. This", "was detected by running '$pParameters->{webserver_binary} -v' and not", "receiving a result containing the case-insensitive word 'Apache'. As", "a result while the install will attempt to continue, the binary", "assumed to correspond with the Web server configuration file (specified", "below) may not be correct:", " $pServerStats->{webserver_conf}"); } else { $pServerStats->{webserver_binary} = $pParameters->{webserver_binary}; } } else { note("The specified webserver_binary=$pParameters->{webserver_binary} option", "is invalid. It specifies a file that either does not exist or is not", "set executable. While the install will attempt to continue, the binary", "assumed to correspond with the Web server configuration file (specified", "below) may not be correct:", " $pServerStats->{webserver_conf}"); } } if (not exists $pServerStats->{webserver_binary}) { # When searching for the binary, search such that we search around the # webserver root first, then we search the system binary locations. my @server_binary_roots = map("$pServerStats->{webserver_root}/$_",("sbin","bin","src")); my $apache_binary = locate_apache_binary(@server_binary_roots); if (not $apache_binary) { # If we haven't found an apache binary by this point, any other searching is # guessing. We should as such, mark it as so. Set the webserver note and # report it in the error log. # System binary roots (guess)? my @system_binary_roots = ( "/usr/sbin","/sbin","/var/sbin", "/usr/bin","/bin","/var/bin", ); $apache_binary = locate_apache_binary(@system_binary_roots); if ($apache_binary) { $pServerStats->{webserver_note} = ("This Web server has a questionable binary. Make certain\n". "it refers to the appropriate Web server binary." ); note_log("Possible incorrect binary detected for the following binary:", $pServerStats->{webserver_conf}); $pServerStats->{webserver_binary} = $apache_binary; } } else { $pServerStats->{webserver_binary} = $apache_binary; } } if (not exists $pServerStats->{webserver_binary}) { return(note_log("Setup is unable to detect the binary associated with the following", "configuration file:", " $pServerStats->{webserver_conf}", "Setup will not configure this server. You may manually install it", "via the 'Specify the Webserver' selection.")); } my $version_string = `$pServerStats->{webserver_binary} -v`; my $define_string = `$pServerStats->{webserver_binary} -V`; my $module_string = `$pServerStats->{webserver_binary} -l`; if ($version_string =~ m@Server version:.*/(\d+)\.(\d+)\.(\d+)@s) { $pServerStats->{webserver_version} = "$1.$2.$3"; $pServerStats->{webserver_release} = $1; $pServerStats->{webserver_major} = $2; $pServerStats->{webserver_minor} = $3; } else { return(error("Invalid / broken apache binary.", "Unable to obtain version values for the server with config file:", " $pServerStats->{webserver_conf}")); } if ($module_string =~ /mod_ssl/) { $pServerStats->{webserver_https} = "yes"; } if ($module_string =~ /mod_so/) { $pServerStats->{webserver_dso} = "yes"; } else { $pServerStats->{webserver_dso} = "no"; } if ($define_string =~ /EAPI/) { $pServerStats->{webserver_api} = "eapi"; } else { $pServerStats->{webserver_api} = "standard"; } my $base_module_dir = "$pGlobals->{module_dir}/apache_$pServerStats->{webserver_version}"; if ($pDistMap->{webserver_conf} eq $pServerStats->{webserver_conf}) { # It is possible that we will need to take special precautions when updating # this server. Some distributions ships with a heavily hacked version of # Apache which will leave us broken. We currently have (and likely won't for # the foreseeable future) no means of detecting this screwy behavior. We, # thus, special case these distributions by providing a special upgrade # module. my $module_dir = "$base_module_dir/non-standard/$pOS->{distribution}/$pOS->{distribution_version}"; my $module = "$module_dir/mod_casp2.$pGlobals->{lib_ext}"; if (-f $module) { $pServerStats->{webserver_module} = $module; } } if (not exists $pServerStats->{webserver_module}) { $pServerStats->{webserver_module} = "$base_module_dir/$pServerStats->{webserver_api}/mod_casp2.$pGlobals->{lib_ext}"; (-f $pServerStats->{webserver_module}) || note("Unable to locate Apache module at the specified path.", "$pServerStats->{webserver_module}"); # Note: We don't return an error here because the possibility exists that the # user will create the directory and file as directed during # installation. We merely note it during caching. } # We should refresh the start script, every time we run cache server. The only # exception is if the start_script was set because of a well known location # for that start script (ie. a system dependent start script was encountered). if ((not $autostart_enabled) || (not exists $pServerStats->{webserver_start_script})) { # Let's see if we can make a last ditch effort at generating a start / stop # script. if (-x $pServerStats->{webserver_binary}) { my $additional_args; if (boolean_value($pServerStats->{webserver_https})) { $additional_args = '-DSSL '; } $pServerStats->{webserver_start_script} = ("$pGlobals->{asphome}/INSTALL/apachectl \"binary=$pServerStats->{webserver_binary}\" ". "\"conf=$pServerStats->{webserver_conf}\" \"args=$additional_args\" start"); $pServerStats->{webserver_stop_script} = ("$pGlobals->{asphome}/INSTALL/apachectl \"binary=$pServerStats->{webserver_binary}\" ". "\"conf=$pServerStats->{webserver_conf}\" stop"); } else { my $start_script; my $stop_script; my $apachectl; foreach ("bin","sbin","src") { # Check for apachectl my $subdir = $_; foreach ("apachectl") { if (-r "$pServerStats->{webserver_root}/$subdir/$_") { $apachectl = "$pServerStats->{webserver_root}/$subdir/$_"; last; } } } if (-x "$apachectl") { $start_script = "$apachectl start"; $stop_script = "$apachectl stop"; } else { my $apachectl = INSTALL::query::user_function ("\Enter the path and file name of the Apache Start Script\n", *confirm_binary_existence, "default=none", "invalid_choice="); if ($apachectl eq "none") { return(undef); } } # We must make certain that the library path for the appropriate chiliasp binaries # is on the libpath already. $pServerStats->{webserver_start_script}= $start_script; # we don't need to set the path for the stop script. $pServerStats->{webserver_stop_script}= $stop_script; } } # Detect secure server ability. if ($pServerStats->{webserver_binary} =~ m@httpsd@) { $pServerStats->{webserver_https} = "yes"; } $pServerStats->{webserver_status_script} = "$pGlobals->{asphome}/INSTALL/apachectl \"binary=$pServerStats->{webserver_binary}\" ". "\"conf=$pServerStats->{webserver_conf}\" status"; return(1); } #------------------------------------------------------------------------------ # This method will ask all of the appropriate questions, to properly configure # an apache server. This method will not, however, do the actual # installation. The name is a bit misleading, since it in truth only gathers # the information necessary for configuring the server. #------------------------------------------------------------------------------ sub configure_unlisted { sub confirm_existence { ($#_ == 0) || die "Invalid number of arguments."; my ($file) = @_; if ($file eq "none") { report(""); my $answer = INSTALL::query::user ("Would you like to cancel the setup","terminal_mark=?","y","default=n"); report(""); if ($answer eq "y") { return(1); } else { # Cause a requery. return(undef); } } elsif (not -f $file) { report("Invalid: The specified file does not exist."); report(""); } return(-f $file); } sub confirm_binary_existence { ($#_ == 0) || die "Invalid number of arguments."; my ($file) = @_; if ($file eq "none") { report(""); my $answer = INSTALL::query::user ("Would you like to cancel the setup","terminal_mark=?","y","default=n"); report(""); if ($answer eq "y") { return(1); } else { # Cause a requery. return(undef); } } elsif (not -x $file) { report("Invalid: The specified binary does not exist or is not executable."); report(""); } return(-x $file); } CONFIGURE_APACHE_CONF: INSTALL::query::user_menu ("Sun Chili!Soft ASP - Apache Configuration", "Because of the way the Apache Web server works, few of the configuration ". "questions listed below can be answered outright. However, wherever ". "possible, default values have been provided for some of the questions.\n". " \n". "Note: To exit out of Web server configuration, type 'none' for the\n". " listed option." ); my $server_conf = INSTALL::query::user_function ("Enter the path and file name of the Apache Web server configuration file\n", *confirm_existence, "default=none", "invalid_choice="); if ($server_conf eq "none") { return(); } $server_conf = realpath($server_conf); my %hash = ( webserver_conf => $server_conf, webserver_type => "apache" ); my $pServerStats = \%hash; # We don't have to error out for this. # We still need to get the Apache Binary. if (not cache_server($pServerStats)) { # Nothing to worry. } print "\n\n"; CONFIGURE_APACHE_BINARY: my $server_binary = INSTALL::query::user_function ("Enter the path and file name of the Apache binary\n", *confirm_binary_existence, "default=$pServerStats->{webserver_binary}", "invalid_choice="); if ($server_binary eq "none") { return(undef); } # Reconfigure, if things changed due to a differing binary. $hash{webserver_binary} = $server_binary; if (not cache_server(\%hash)) { error ("Error occurred while trying to configure Apache Server"); error ("This must be either because of the way your Apache server is configured."); error ("Please verify your Apache configuration settings and try again! "); report("Press Enter to continue ..."); ; goto CONFIGURE_APACHE_CONF; } return(\%hash); } ################################################## # Start / Stop Apache rpm on (X) distribution. ################################################## sub restart_apache { (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; if (exists $pServerStats->{webserver_stop_script} && exists $pServerStats->{webserver_start_script}) { my $result = not system_log($pServerStats->{webserver_stop_script}); INSTALL::common::usleep(50000); $result |= not system_log($pServerStats->{webserver_start_script}); return($result); } else { return(0); } } sub start_apache { (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; if (exists $pServerStats->{webserver_start_script}) { my $result = not system_log($pServerStats->{webserver_start_script}); return($result); } else { return(0); } } sub stop_apache { (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; if (exists $pServerStats->{webserver_stop_script}) { my $result = not system_log($pServerStats->{webserver_stop_script}); INSTALL::common::usleep(50000); return($result); } else { return(0); } } #------------------------------------------------------------------------------ # Perform the job of apxs. If a fourth argument value (which evaluates to true), # does not exist, the default semantics of apxs are used. That is, the new # module is appended to the end of the AddModule / LoadModule lists. # Otherwise, if it does evaluate to true, the module will be inserted at the # head of the list (ie. prepended). #------------------------------------------------------------------------------ sub apxs { (($#_ == 1) || ($#_ == 2)) || die "Invalid number of arguments."; my ($conf,$entry_point,$module_name,$prepend) = @_; my $dupname = "$conf.pre-chiliasp"; if (not -f $module_name) { return(error("Specified module '$module_name' does not exist.")); } unlink($dupname); copy($conf,$dupname); unless(open(SRC,"<$dupname") && open(HTTPD,">$conf")) { # Back out any changes. close(SRC); close(HTTPD); unlink($conf); copy($dupname,$conf); unlink($dupname); return(error("Unable to open $conf for modification.")); } my $module_root = INSTALL::common::strip_extension(basename($module_name)); my $quoted_module_root = quotemeta($module_root); my @lines = grep { (not m@[/\s]$quoted_module_root@) && (not /Chili!Soft/) } ; my @result; my $line_count = $#lines; my $ClearModule_index = -1; if ($pOS->{distribution} =~ /SuSE/i && $pOS->{distribution_version} >= 7.2 && grep { /^\s*Include.*suse_loadmodule.conf/i } @lines) { for (my $i=$line_count; $i >= 0; $i--) { if ($lines[$i] =~ /^\s*Include.*suse_loadmodule.conf/i) { $ClearModule_index = $i; last; } } } elsif (grep { /^\s*ClearModuleList/ } @lines) { ### First find the ClearModuleList line (or actually the first ### non-comment-line, before that). # Accomodate SuSE bug of duplicating the LoadModule / AddModule section in # the httpd.conf file. We make sure we add ourself around the last # ClearModuleList, rather than the first. for (my $i=$line_count; $i >= 0; $i--) { if ($lines[$i] =~ /^\s*ClearModuleList/) { $ClearModule_index = $i; last; } } } if ($ClearModule_index != -1) { # Search for first previous non-comment line. for (my $i = $ClearModule_index - 1; $i >= 0; $i--) { if ($lines[$i] !~ /^\s*\#/) { $ClearModule_index = $i; last; } } ### Then find the last AddModule index (or actually the first ### non-comment-line, after that). my $last_AddModule_index; for (my $i=$line_count; $i >= 0; $i--) { if ($lines[$i] =~ /^\s*AddModule/) { $last_AddModule_index = $i; last; } } if (not $last_AddModule_index) { $last_AddModule_index = $ClearModule_index + 1; } # Discover if we are in a block my $insideIfDefine = 0; for (my $i = 0; $i <= $last_AddModule_index; $i++) { if ($lines[$i] =~ m@^\s* 0) { # We will make sure to add ourself after the appropriate closing # (I certainly hope their httpd.conf is valid). for (my $i = $last_AddModule_index + 1; ($i <= $line_count); $i++) { if ($lines[$i] =~ m@^\s*{custom_install}); sub detect_supported_versions { my @supported_versions; local *MODULES_DIR; if (opendir(MODULES_DIR,$pGlobals->{module_dir})) { my @subdirs = readdir(MODULES_DIR); closedir(MODULES_DIR); foreach (@subdirs) { if (/apache_([0-9]+\.[0-9]+\.[0-9]+)/) { push @supported_versions,$1; } } return(@supported_versions); } else { error("Unable to read module directory in installation:", " $pGlobals->{module_dir}"); exit(1); } } sub exit_parent { ($#_ == 0) || die "Invalid number of arguments."; my ($pid) = @_; if (interactive) { INSTALL::common::signal_spinner($pid); } else { waitpid($pid,0); } return(undef); } (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; (ref($pServerStats)) || die "Invalid argument passed."; my @supported_versions = detect_supported_versions; ########## Check the server statistics for a valid setup. if (not -d $pServerStats->{webserver_root}) { return(error("The specified Web server root '$pServerStats->{webserver_root}' does not exist.")); } if (not -f $pServerStats->{webserver_conf}) { return(error("The specified Web server configuration file '$pServerStats->{webserver_conf}'", "does not exist.")); } if (not -x $pServerStats->{webserver_binary}) { return(error("The specified Web server executable '$pServerStats->{webserver_binary}' does not", "exist or is not executable.")); } if ($pServerStats->{webserver_type} !~ /apache/i) { return(error("Attempting to configure a '$pServerStats->{webserver_type}' server with the", "Apache module.")); } # Now that the configuration appears correct, we should recache the server # with the same information, so that the DSO flag can be adjusted between # execution cycles. Otherwise, the user would be required to refresh their # webserver list. cache_server($pServerStats); if (not boolean_value($pServerStats->{webserver_dso})) { if (not interactive) { return(error("I have detected that the specified Web server does not use dynamic", "modules (DSO), yet the installer requires this. Please recompile", "your Web server to support DSO. Refer to Apache documentation on", "enabling DSO support.")); } else { INSTALL::query::user_menu ( "Sun Chili!Soft ASP - Non-DSO Apache Configuration", "I have detected that the specified Web server does not use dynamic modules (DSO). ". "It should be noted that to get Sun Chili!Soft ASP functional, you have two options. ". "If you would prefer to continue on with the installation, you will be required ". "to recompile your Apache Web server with the Sun Chili!Soft ASP module (refer to the ". "README for details). Another option is to skip the ". "installation in favor of recompiling DSO support into Apache. While both ". "options will work equally well, it is suggested that you enable DSO support, ". "since it has numerous benefits over the statically linked version (refer to ". "Apache documentation for details).\n ". "\n ". "Note: If you opted to enable DSO support in Apache (ie. answered yes to\n". " the question below), you will need to perform the following steps,\n". " once the necessary Apache modifications have been made, to\n". " finalize your install:\n". " cd $pGlobals->{asphome}\n". " ./configure-server" ); my $skip_install = INSTALL::query::user ("Would you like to skip installation to enable DSO support", "default=y","n", "terminal_mark=?"); if ($skip_install eq "y") { return(undef); } } } ########## If the user wants auto startup of apache and it's supported ... my $dso = boolean_value($pServerStats->{webserver_dso}); my $start_apache = 0; my $supported_autostart = (exists $pServerStats->{webserver_start_script} && exists $pServerStats->{webserver_stop_script}); if ($supported_autostart) { $start_apache = 1; if (exists $pParameters->{webserver_restart}) { $start_apache = boolean_value($pParameters->{webserver_restart}); } } ### FIXME: We probably need a more distribution specific section of code here. if (interactive) { if ($supported_autostart && $custom_install && $dso) { $start_apache = INSTALL::query::boolean_default ("Would you like me to restart this Apache server for you", $start_apache); } } # Check version support. my $quoted_version = quotemeta($pServerStats->{webserver_version}); if (not grep { /$quoted_version/ } @supported_versions) { my $server_path; if (exists $pServerStats->{webserver_module}) { $server_path = $pServerStats->{webserver_module}; $server_path =~ s@/[^/]*$@@; } else { $server_path = "$pGlobals->{asphome}/module/apache_$pServerStats->{webserver_version}/$pServerStats->{webserver_api}"; } error("The specified version of Apache ($pServerStats->{webserver_version}) is not currently supported."); note("Regardless of this fact, you may be able to build your own module that", "supports this version of Apache. Refer to Sun Chili!Soft ASP documentation", "for information on building your own module. After that module has", "been built, proceed by following these steps:", " (1) mkdir -p $server_path", " (2) cp /mod_casp2.$pGlobals->{lib_ext} $server_path", " (3) Rerun the ".(($0 =~ /[_-]server/i) ? (basename($0)." script.") : "the installer by executing the following script:\n\t$pGlobals-{asphome}/INSTALL/install."), "", "By placing the file into the created module directory, the installer will", "recognize it as a supported Web server and act accordingly."); report("Press Enter to continue ..."); ; return(undef); } elsif (not -f $pServerStats->{webserver_module}) { error("The needed server module does not exist in your installation:"," $pServerStats->{webserver_module}."); report("Press Enter to continue ..."); ; return(undef); } #### If the user calls us to configure the hostname, then we will do it here. my $hostname; my $configure_hostname = boolean_value($pParameters->{configure_hostname}); if ($configure_hostname) { use Sys::Hostname; use Socket; $hostname = hostname(); my $address = gethostbyname($hostname); $hostname = gethostbyaddr($address,AF_INET); RETRY_HOSTNAME_CONFIGURE: if (interactive) { INSTALL::query::user_menu ( "Sun Chili!Soft ASP - Hostname Configuration", "The setup program needs to configure the \"ServerName\" directive of your Apache ". "webserver. The ServerName directive allows a Web server to distinguish itself ". "from its internally visible DNS name. For example, a server might be known as ". "webserver-1, to the internal network, but be known as www.yourcompany.com to ". "machines outside your internal network. These cases can arise because of ". "varying issues: firewalls, external DNS entries differing from internal DNS ". "entries, proxying, etc.\n \n". "Note: Due to the way in which the directive works, the specified hostname\n". " must be either a valid DNS entry, a valid entry in your /etc/hosts\n". " file, or the hosts IP address.\n \n". "If you wish to skip this configuration, type none when prompted. You will then ". "be required to manually set your ServerName directive in you server's ". "configuration file ($pServerStats->{webserver_conf}). \n ", "For your convenience, the setup program has done its best to detect the hostname ". "of the local machine, and shall use this value as the user default. If this ". "value is valid, merely press enter to confirm the selection, otherwise enter a ". "valid value using the rules specified above as a basis." ); my $answer = INSTALL::query::user ("Hostname of your machine ", "terminal_mark=:", "default=$hostname"); if ($answer eq "none") { INSTALL::query::user_menu ( "The \"ServerName\" of your apache Web server is not configured. Sun Chili!Soft ASP ". "cannot run without this properly configured. You will have to manually fill in the ". "\"ServerName\" directive in your $pServerStats->{webserver_conf} file. " ); report("Press Enter to continue ..."); ; $configure_hostname = 0; } else { $hostname = $answer; if (not gethostbyname($answer)) { print STDERR "\n"; note("The specified ServerName was invalid."); report("Press Enter to continue ..."); ; goto RETRY_HOSTNAME_CONFIGURE; } } } } if (interactive) { print STDERR ("Configuring the $pServerStats->{webserver_name} Web server ... "); } my $pid = fork; if ($pid) { ##########========== Parent # Now start updating the configuration file. unlink("$pServerStats->{webserver_conf}.pre-chiliasp"); copy($pServerStats->{webserver_conf},"$pServerStats->{webserver_conf}.pre-chiliasp"); ########## Update the httpd.conf file to refer to the appropriate locations. if (boolean_value($pServerStats->{webserver_dso})) { if (not apxs($pServerStats->{webserver_conf},"casp2_module", $pServerStats->{webserver_module})) { error("Unable to configure the server due to apxs failure."); # Run cleanup code. return(exit_parent($pid)); } } my $dupname = "$pServerStats->{webserver_conf}.chiliasp-install"; unlink($dupname); copy($pServerStats->{webserver_conf},"$dupname"); unless (open(SRC,"<$dupname") && open(HTTPD,">$pServerStats->{webserver_conf}")) { # Back out any changes. close(SRC); close(HTTPD); unlink("$pServerStats->{webserver_conf}"); copy("$pServerStats->{webserver_conf}.pre-chiliasp",$pServerStats->{webserver_conf}); unlink($dupname); report("Warning: ","Unable to open $pServerStats->{webserver_conf} for modification."); # Run cleanup code. return(exit_parent($pid)); } unlink($dupname); my $last_line; while () { $last_line = $_; s/^(MaxRequestsPerChild\s+)\d+/MaxRequestsPerChild 30000/; if ($configure_hostname) { s/^(\S?ServerName\s+.*)/ServerName $hostname/; } print HTTPD if ((! /AddHandler.*\.as[pa]|CaspLib|\#\# Chili!Soft ASP/i)); } if (not chomp $last_line) { print HTTPD "\n"; } print HTTPD "## Sun Chili!Soft ASP installer\n"; print HTTPD ("AddHandler chiliasp .asp\n". "AddHandler chiliasp .asa\n". "CaspLib $pServerStats->{engine_dir}\n" ); close HTTPD; close SRC; my $restarted = 0; if ($start_apache) { $restarted = restart_apache($pServerStats); } exit_parent($pid); if (interactive && (not $restarted)) { print STDERR "\n"; note("For your Web server to function properly, you need to restart", "it. The configuration file for this Web server is:", " $pServerStats->{webserver_conf}"); report("Press Enter to continue ..."); ; } return(1); } else { ##########========== Child if (interactive) { INSTALL::common::spinner_wait_signal; } exit(0); } } #------------------------------------------------------------------------------ # This method when invoked on information regarding a specific Apache server # will remove any remnants of Sun Chili!Soft ASP from that server, as well as # remove any server, which points to that Apache server. #------------------------------------------------------------------------------ sub uninstall { (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; (ref($pServerStats)) || die "Invalid argument passed."; my $retVal = 1; if (-f $pServerStats->{webserver_conf}) { unlink("$pServerStats->{webserver_conf}.post-chiliasp"); copy($pServerStats->{webserver_conf},"$pServerStats->{webserver_conf}.post-chiliasp"); unless (open(SRC,"<$pServerStats->{webserver_conf}.post-chiliasp") && open(HTTPD,">$pServerStats->{webserver_conf}")) { error("Unable to open $pServerStats->{webserver_conf} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the httpd.conf file. ########## Keep track of the PidFile directive. my $pidFile; while () { print HTTPD if ((! /AddHandler.*\.as[pa]|CaspLib|Chili!Soft ASP|mod_casp2|casp2_module/i)); } close HTTPD; close SRC; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_conf}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_conf} file.", "The Web server may have previously been removed."); $retVal = 2; } my $restarted = 0; my $dso = boolean_value($pServerStats->{webserver_dso}); ########## Restart the webserver if appropriate. if ((exists $pServerStats->{webserver_start_script} && exists $pServerStats->{webserver_stop_script}) && $dso) { my $answer = "y"; my $restart_apache = 0; # initialize this to zero. if (exists $pParameters->{webserver_restart}) { $restart_apache = boolean_value($pParameters->{webserver_restart}); } if (interactive && !$restart_apache) { $answer = INSTALL::query::user ("Would you like this Apache Web server restarted", "terminal_mark=?", "default=y", "n"); } if ($answer eq "y") { $restarted = restart_apache($pServerStats); } if (interactive && (not $restarted)) { note("For your Web server to function properly, you need to restart", "it. The configuration file for this Web server is:", " $pServerStats->{webserver_conf}"); report("Press Enter to continue ..."); $retVal = 2; ; } } if (interactive && (not $dso)) { note("The Apache Web server associated with this Sun Chili!Soft ASP engine was", "non-DSO. For the Web server to function properly in the future, you", "will need to stop the Web server and rebuild Apache without the ", "Sun Chili!Soft ASP module. The following information pertains to the", "webserver:", " Main configuration file: $pServerStats->{webserver_conf}", " Binary: $pServerStats->{webserver_binary}", " Version: $pServerStats->{webserver_version}", " Port: $pServerStats->{webserver_port}", " Root: $pServerStats->{webserver_root}"); report("Press Enter to continue ..."); ; } return($retVal); } 1;