package INSTALL::webserver; use POSIX; use INSTALL::common; use INSTALL::os; use INSTALL::global; use INSTALL::parameter; use INSTALL::query; use INSTALL::ini; use INSTALL::caspeng; use INSTALL::apache; use INSTALL::netscape; use INSTALL::zeus; use strict; no strict 'refs'; my $debug = 0; my $pGlobals = \%INSTALL::global::variables; my $pParameters = \%INSTALL::parameter::variables; my $pOS = \%INSTALL::os::Details; my @CONST_WebserverModules = ("apache","netscape","zeus"); #------------------------------------------------------------------------------ # This method takes a reference to a server hash (ie. a hash containing conf, # type, etc.) and dumps it to an ini file cache. Upon success, a value which # evaluates to true is returned. #------------------------------------------------------------------------------ sub save_server { ($#_ == 0) || die "Invalid number of arguments."; my ($pServerHash) = @_; my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $pIni = INSTALL::ini::open($cache_file); if ($pIni) { my $pSection = INSTALL::ini::insertSection($pIni,$pServerHash->{webserver_conf}); foreach(keys %$pServerHash) { # # For debugging: # print "webserver::cache_server> $_ = $server_stats{$_}\n"; $pSection->{$_} = $pServerHash->{$_}; } if (not INSTALL::ini::save($pIni,$cache_file)) { return(error("Unable to store server configuration to cache file $cache_file.")); } } else { return(error("Unable to open Web server cache file $cache_file.")); } return(1); } #------------------------------------------------------------------------------ # This method takes a list of references to a server hashes (ie. a hash # containing conf, type, etc.) and dumps them to an ini file cache. See # save_server. Success occurs if all of the servers were saved, successfully. #------------------------------------------------------------------------------ sub save_servers { my @pServerHashes = @_; my $result = 1; foreach my $pServerHash (@pServerHashes) { $result &= save_server($pServerHash); } return($result); } #------------------------------------------------------------------------------ # This method takes a configuration file name and retrieves the server # information for that server from the ini file cache. If no such server # exists, undef is returned. Otherwise, a reference to the server hash is # returned. #------------------------------------------------------------------------------ sub load_server { ($#_ == 0) || die "Invalid number of arguments."; my ($server_conf) = @_; my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $pIni = INSTALL::ini::open($cache_file); if ($pIni) { my $pSection = INSTALL::ini::openSection($pIni, $server_conf); if ($pSection) { return($pSection); } else { return(error("Could not find section $server_conf in Web server cache file:", " $cache_file.")); } } else { return(error("Could not open Web server cache file:", " $cache_file.")); } } #------------------------------------------------------------------------------ # Similar to load_server, except that all entries are returned as an array of # references. If no entries exist, an empty array is returned. #------------------------------------------------------------------------------ sub load_servers { ($#_ < 0) || die "Invalid number of arguments."; my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $pIni = INSTALL::ini::open($cache_file); if ($pIni) { my @sections = INSTALL::ini::getSectionNames($pIni); my @pServerHashes; foreach my $section (@sections) { push @pServerHashes, INSTALL::ini::openSection($pIni, $section); } return(@pServerHashes); } else { return(); } } #------------------------------------------------------------------------------ # This method takes a configuration file, <$webserver_conf>, and type, # <$webserver_type>, and invokes the INSTALL::$webserver_type::cache_server # method. If this invocation is successful, the returned data is stored # in the webserver cache. If this function succeeds, a true value is returned # otherwise, undef is returned. #============================================================================== # Implementors note: # (1) This method calls into the respective perl module for the webserver in # question (ie. it keys off of type). It is assumed that this module will # contain a method named cache_server which takes one parameter, that being # a reference to a hash. This hash is guaranteed to contain conf and type # as parameter keys. The result is expected to be non-undef on success # and undef otherwise. #------------------------------------------------------------------------------ sub cache_server { ($#_ >= 1) || die "Invalid number of arguments."; my ($webserver_type,$webserver_conf,%optional_server_stats) = @_; my $cache_server = "INSTALL::${webserver_type}::cache_server"; my $result; if (defined &{$cache_server}) { my %server_stats = ( webserver_type => $webserver_type, webserver_conf => $webserver_conf ); if (%optional_server_stats) { %server_stats = (%server_stats,%optional_server_stats); } my $pServerStats = \%server_stats; $result = &{$cache_server}($pServerStats); if (exists $pServerStats->{webserver_port}) { use INSTALL::services; INSTALL::services::invalidate_ports($pServerStats->{webserver_port},1); } if ((exists $pServerStats->{webserver_version}) && (exists $pServerStats->{webserver_type})) { # Keep track of all webservers configured. if ($ENV{WEBSERVER_TYPES}) { $ENV{WEBSERVER_TYPES} .= " "; } $ENV{WEBSERVER_TYPES} .= ucfirst("$pServerStats->{webserver_type}/$pServerStats->{webserver_version}"); } if ($result) { return(save_server($pServerStats)); } } else { return(error("Unable to locate a module correlating to $webserver_type")); } return($result); } #------------------------------------------------------------------------------ # This method takes a hash in the format returned from locate_server(s). It # subsequently invokes the cache_server function for each and every server # listed in the hash. #------------------------------------------------------------------------------ sub cache_servers { my %server_hash = @_; my $result; foreach my $type (keys %server_hash) { my $pConfs = $server_hash{$type}; ref($pConfs) || die "Invalid server entry."; foreach my $conf (@$pConfs) { cache_server($type,$conf) && $result++; } } return($result); } #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # External functions #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #------------------------------------------------------------------------------ # This method returns a list of the known server configuration files. Known # here, means the list of servers contained in the webserver cache. #------------------------------------------------------------------------------ sub list_servers { ($#_ < 0) || die "Invalid number of arguments to list_servers."; return(map {$_->{webserver_conf}} load_servers); } #------------------------------------------------------------------------------ # Using the specified directory as a possible configuration directory, try # to locate any and all webservers located in that directory (or imemediate # subdirectories, as the rules apply). This method will return a hash # keyed off of server type. Each value will itself be a reference to a list of # webserver configuration files (of the keyed server type). #============================================================================== # Implementors note: # (1) It is assumed that each webserver module (ie. apache, netscape, etc). # will have a locate_server method which will return a list of # configuration files, as appropriate. #------------------------------------------------------------------------------ sub locate_server { ($#_ == 0) || die "Invalid number of arguments."; my ($conf_path) = @_; my @result; foreach my $module (@CONST_WebserverModules) { my $module_method = "INSTALL::${module}::locate_server"; my %server_confs = map(($_=>undef),&$module_method($conf_path)); if (%server_confs) { push @result,($module=>[keys %server_confs]); } } return(@result); } #------------------------------------------------------------------------------ # Recursively traverse all directories starting at the top-level directory # specified by , attempting to find all webservers contained # under that directory. Upon successfully establishing at least one webserver, # 1 is returned. Otherwise, undef is returned. The optional second argument # specifies the maximum depth that the call may traverse to. #------------------------------------------------------------------------------ { my %disabled_directories; sub isDisabledDirectory { if (not keys %disabled_directories) { %disabled_directories = ( "/proc" => undef, "/dev" => undef, "/devices" => undef, map(($_=>undef),@{$pOS->{disabled_mountpoints}}) ); #### ## if ($debug) { ## my $key; ## foreach $key (keys %disabled_directories) { ## print "Key is $key and value is $disabled_directories{$key} \n"; ## } ## ; ## } #### } return(exists $disabled_directories{$_[0]}); } } sub locate_servers { sub merge_locate_servers { my @result; foreach my $type (@CONST_WebserverModules) { my @server_confs; foreach(@_) { if (exists $_->{$type}) { push @server_confs, @{$_->{$type}}; } } # Strip redundancy. my %server_confs = map(($_=>undef),@server_confs); if (%server_confs) { push @result,($type => [ keys %server_confs ]); } } return(@result); } sub internal_locate { my ($search_path,$depth) = @_; my %result; my @subdirs; if ($depth <= 0) { return(); } local *DIR; unless(opendir(DIR,"$search_path")) { return(error("Unable to open $search_path in locate_servers.")); } if ($search_path eq '/') { $search_path = ""; } foreach my $file (grep { ($_ ne ".") && ($_ ne "..") } readdir(DIR)) { my $path = "$search_path/$file"; if ((not -l $path) && (-d $path) && (not isDisabledDirectory($path))) { push @subdirs, $path; } } closedir(DIR); foreach(@subdirs) { #### ## open(LOCATE_SERVERS,">>$pGlobals->{log_dir}/locate_servers.log"); ## print LOCATE_SERVERS "$_\n"; ## close(LOCATE_SERVERS); #### my %here = locate_server($_); my %below = internal_locate($_,$depth-1); %result = merge_locate_servers(\%result,\%here,\%below) } return(%result); } # Now the code for locate_server continues. ($#_ == 0) || ($#_ == 1) || die "Invalid number of arguments."; my ($search_path, $depth) = @_; if (not $depth) { $depth = 1000000; } if (not length($search_path)) { $search_path = `pwd`; } my %here = locate_server($search_path); my %below = internal_locate($search_path,$depth); return(merge_locate_servers(\%here,\%below)); } #------------------------------------------------------------------------------ # This method allows a user to attempt to recache a specific webserver. To # do this, pass in the associated configuration file of that webserver. Upon # successful recaching, a value which will evaluate to true is returned. # Otherwise, undef is returned. It should be noted that this method will error # out immediately if the specified webserver configuration file does not exist. #------------------------------------------------------------------------------ sub recache_servers { if ($#_ >= 0) { my (@server_confs) = @_; my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $pIni = INSTALL::ini::open($cache_file); my $result; if ($pIni) { foreach my $server_conf (@server_confs) { my $pSection = INSTALL::ini::openSection($pIni,$server_conf); if (not $pSection) { return(undef); } else { $result = cache_server($pSection->{webserver_type},$server_conf,%$pSection); if (not $result) { # Delete the entry from the ini file. INSTALL::ini::deleteSection($pIni,$server_conf); INSTALL::ini::save($pIni,$cache_file); } } } } return($result); } else { return(1); } } #------------------------------------------------------------------------------ # This is an interactive (or non_interactive, if appropriate parameters are # provided via INSTALL::parameter) method which will attempt to discover the # location of all of the installed webservers on the box. In the interactive # variant, the user will be queried for how aggressive the search will be). In # the non_interactive variant, the specified path (specified via # $INSTALL::parameter::variables{webserver_path}) will be searched for valid # servers. If no server are found, undef will be returned. Otherwise, 1 is # returned. #------------------------------------------------------------------------------ my @options = ( [ "Exhaustive search (slow)", [ [ "/" ] ] ], [ "Search in: /usr, /opt, /etc, /var (moderate)", [ ["/usr"], ["/opt"], ["/etc"], ["/var"] ] ], [ "Search the common Web server locations (fast)", [ ["/etc",1], ["/opt",2], ["/usr/local",2], ["/usr",2], (($pOS->{os} =~ /AIX/i) ? ["/usr/opt",1] : ()), (($pOS->{os} =~ /Linux/i) ? ["/var",2] : ()) ] ] ); sub build_server_cache { my @scandirs = @_; my $result = undef; if (exists $pParameters->{webserver_path}) { my %servers = locate_server($pParameters->{webserver_path}); if (%servers) { $result = cache_servers(%servers); } } elsif (exists $pParameters->{webserver_conf}) { $result = cache_servers(locate_server(dirname($pParameters->{webserver_conf}))); } elsif (@scandirs) { foreach(@scandirs) { my %servers = locate_servers($_); if (%servers) { $result = cache_servers(%servers); } } } else { my $default = 2; my $type = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Auto-Detection", "Setup will now conduct a search of your system to generate a list ". "of installed Web servers. On the next screen, you have the option to ". "enable ASP support for one of these detected Web servers. If you want ". "to skip this step, you can specify the pathname to a specific Web server ". "by choosing option 4 below.", "Which type of search would you like to perform", "terminal_mark=?", map($_->[0],@options), "Don't search (specify Web server on next screen)", "default=$default"); if ($type == (scalar(@options) + 1)) { $result = 1; } else { print STDERR ("Searching for Web servers ... "); my $pid = fork; if (not $pid) { $result = 0; foreach my $pArgs (@{$options[$type - 1]->[1]}) { my %servers = locate_servers(@$pArgs); if (%servers) { $result |= cache_servers(%servers); } } exit(not $result); } else { INSTALL::common::spinner_wait($pid); print "\n"; if (not $?) { $result = 1; } } } } # Confirm that all of the conf files listed in the webserver cache are valid. # If not create a remove list, then remove them. my @delete_list; foreach(list_servers) { if (not -f $_) { push @delete_list,$_; } } if (@delete_list) { my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $pIni = INSTALL::ini::open($cache_file); if (not $pIni) { return(error("Could not open $cache_file.")); } foreach(@delete_list) { INSTALL::ini::deleteSection($pIni,$_); } INSTALL::ini::save($pIni,$cache_file); } return($result); } #------------------------------------------------------------------------------ # This method is the main interface for installing an unlisted server. It will # call into the appropriate webserver pm, to configure the webserver in a # webserver dependant fashion. #============================================================================== # Implementors note: # (1) Each webserver pm is assumed to have a configure_unlisted method which # will query the user for all of the pertinent information about the # server, and which will return a hash containing that information. If # the resultant hash does not contain a conf member (which specifies the # servers document root directory), it is assumed that the configuration # failed. It should be ****NOTED**** that the actual configuration of the # server does not happen here, but instead in configure. #------------------------------------------------------------------------------ sub configure_unlisted { my @webservers = ("Apache", "Netscape / iPlanet", "Zeus"); if ($pOS->{os} =~ /AIX/i) { push @webservers, "IBM HTTP Server"; } # List more webservers here as they become appropriate my $cache_file = "$pGlobals->{install_dir}/.webserver-cache"; my $type = INSTALL::query::user_menu ("Sun Chili!Soft ASP - User-specifed Web Server Configuration", "Listed below are the types of Web servers to which this version of Sun Chili!Soft ". "ASP will install:", "Which Web server type do you want to configure", "terminal_mark=?", @webservers, "Cancel user-specified Web server configuration." ); my $result = undef; if ($type <= scalar(@webservers)) { my @pServerStats; for($webservers[$type - 1]) { (/apache/i || /IBM HTTP/i) && do { @pServerStats = INSTALL::apache::configure_unlisted; last; }; /netscape/i && do { @pServerStats = INSTALL::netscape::configure_unlisted; last; }; /zeus/i && do { @pServerStats = INSTALL::zeus::configure_unlisted; last; }; error("Unsupported Web server used in configure_unlisted."); exit(1); } if (@pServerStats) { $result = save_servers(@pServerStats); } } return($result); } #------------------------------------------------------------------------------ # Returns a hash table which maps all configured webservers (on the entire # box) to their respective engines. The information contained in each hash # value is a reference to a hash which contains the server configuration for # that server (a la .installed_db). # # Note: If cross-linking is occurring (ie. multiple servers are installed to # the same webserver) ... something which is disallowed in 3.6.0S on ... # the last server found to be linked to the said webserver will be # the hashed value. However, to aid in tracking these down, a note # will be appended to the installer_log indicating that a cross-link # was found. #------------------------------------------------------------------------------ sub generate_server_map { ($#_ < 0) || die "Invalid number of arguments."; my $pGlobalIni = INSTALL::ini::open($pGlobals->{chili_ini}); my %found_servers; if ($pGlobalIni) { # Truly global scope. Detect all servers on the box, and check # cross-linking with that knowledge. my @global_sections = INSTALL::ini::getSectionNames($pGlobalIni); # Use this if we are supporting only one server to search. # my @global_sections = $pGlobals->{asphome}; foreach my $local_section (INSTALL::ini::getSectionNames($pGlobalIni)) { my $pLocalIni = INSTALL::ini::open("$local_section/.installed_db"); if ($pLocalIni) { foreach my $local_server (INSTALL::ini::getSectionNames($pLocalIni)) { my $pSection = INSTALL::ini::openSection($pLocalIni,$local_server); my $webserver_conf = $pSection->{webserver_conf}; if (exists $found_servers{$webserver_conf}) { note_log("Found pre-existing cross-linked server:", " Web Server configuration: $pSection->{webserver_conf}", " ASP Server Directory: $local_server"); } $found_servers{$pSection->{webserver_conf}} = INSTALL::ini::openSection($pLocalIni,$local_server); } } } } return(%found_servers); } #------------------------------------------------------------------------------ # Similar to load_servers, except that instead of merely returning an array # of references to the webserver information, the array will contain references # to webserver information from .webserver-cache and .installed-db files. The # rule will be, if a webserver is currently linked to by a Chili!Soft ASP # server, the information that will be appended to the list will be the # information relating to that asp-to-webserver linkage (which is itself # contains both webserver_ and engine_ statistics). This method # is kind of a mishmash between load_servers and generate_server_map. # # Example: # @pServerHashes = load_servers; # [ {server info 1} {server info 2} ] # # @pServerLinks = load_server_links; # [ {server info 1} {engine info 2} ] # # where {server info x} is the information collected for a webserver from the # .webserver-cache and {engine info x} is the information relating to the # engine linked to the association 'x' webserver gleened from the # .installed_db. # # In the previous example, load_servers merely returned the two servers as # depicted in the .webserver-cache. The latter example using load_server_links # returns information that {server info 1} represented an unlinked server and # that {server info 2} was linked to a Chili!Soft ASP server with combined # details of {engine info 2}. #------------------------------------------------------------------------------ sub load_server_links { my @pServerHashes = load_servers; my %server_map = generate_server_map; my @result; foreach my $pServerHash (@pServerHashes) { if (exists $server_map{$pServerHash->{webserver_conf}}) { push @result, $server_map{$pServerHash->{webserver_conf}}; } else { push @result, $pServerHash; } } return(@result); } #------------------------------------------------------------------------------ # This method attempts to discover a link between the specified webserver # configuration file, and any currently installed Chili!ASP engine cluster. # If no such linkage exists, undef is returned. Otherwise, the information # regarding the specified server is returned in a hash. #============================================================================== # Implementor's note: # (1) This depends upon the installed_db cache containing engine entrees # specifying a key of 'engine_name'. # (2) Also required is the 'webserver_conf' key. #------------------------------------------------------------------------------ sub discover_linked_server { ($#_ == 0) || die "Invalid number of arguments."; my ($conf) = @_; my $pIni = INSTALL::ini::open($pGlobals->{installed_db}); if (not $pIni) { return(error("Could not open $pGlobals->{installed_db}.")); } my @section_list = INSTALL::ini::getSectionNames($pIni); my %server_details; foreach(@section_list) { my $pSection = INSTALL::ini::openSection($pIni,$_); if ($pSection->{webserver_conf} eq $conf) { %server_details = %{$pSection}; } } return(%server_details); } #------------------------------------------------------------------------------ # This method queries the user for which server they want to install to (of # those listed in the webserver cache). If there are none in the cache, and # they choose unlisted, the unlisted server will be checked for existance # prior to installation. #============================================================================== # Implementors note: # (1) Each webserver pm is assumed to have a configure method which will take # a hash as a parameter and use the information contained in that hash # to configure a server. This method should return undef upon failure, # non-undef on success. #------------------------------------------------------------------------------ sub interactive_configure { RETRY_CONFIGURE: recache_servers(list_servers); my @pServerHashes = load_server_links; my @CrossLinked = (); my @webserver_options = (); my $default; foreach my $pServerHash (@pServerHashes) { my $server_text; if (boolean_value($pServerHash->{webserver_bundled})) { $server_text .= "Bundled "; $default = @webserver_options + 1; } $server_text .= $pServerHash->{webserver_name}; if (boolean_value($pServerHash->{webserver_https})) { $server_text .= " Secure Server"; } else { $server_text .= " Web server"; } if (exists $pServerHash->{engine_dir}) { # Cross linked server, which type are you? if ($pServerHash->{engine_dir} eq "$pGlobals->{asphome}/$pServerHash->{engine_name}") { # Local cross-link $server_text .= " <<$pServerHash->{engine_name}>>"; push @CrossLinked,1; } else { #External / Global cross-link $server_text .= " <<$pServerHash->{engine_dir}>>"; push @CrossLinked,2; } } else { # Not cross linked. push @CrossLinked,0; } $server_text .= ("\n". " Settings file: $pServerHash->{webserver_conf}\n". " Port: $pServerHash->{webserver_port}" ); push @webserver_options, $server_text; } my $index; if (@webserver_options) { $index = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Configuration", "The following list contains all currently detected Web servers. If the ". "Web server for which you want to enable ASP support appears below, enter ". "the number that corresponds to the Web server. If the Web server is not ". "listed, you can manually specify Web server information to aid in detection, ". "direct Setup to try to detect more Web servers, or delay Web server ". "configuration until another time.", "Which configuration option would you like to perform", "terminal_mark=?", @webserver_options, "Specify the Web server.", "Attempt to auto-detect more Web servers.", "Do not configure a Web server.", ($default ? "default=$default" : ()) ); } else { $index = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Configuration", "No Web servers have been detected. As options, you can manually specify Web ". "server information to aid in detection, direct Setup to try to detect more Web ". "servers, or delay Web server configuration until another time.", "Which configuration option would you like to perform", "terminal_mark=?", "Specify the Web server.", "Attempt to auto-detect more Web servers.", "Do not configure a Web server.", ); } print "\n"; if ($index == (@webserver_options + 1)) { configure_unlisted; goto RETRY_CONFIGURE; } elsif ($index == (@webserver_options + 2)) { build_server_cache; goto RETRY_CONFIGURE; } elsif ($index == (@webserver_options + 3)) { return; } else { $index--; my $crossLinked = $CrossLinked[$index]; my $pServerHash = $pServerHashes[$index]; if ($crossLinked) { note("You cannot install to a Web server which has already been linked to by", "another Sun Chili!Soft ASP server. The currently linked ASP", "server is:", " $pServerHash->{engine_dir}", ""); if ($crossLinked == 2) { # We don't support cross installation uninstalls. report("Press Enter to return to the previous menu ..."); ; goto RETRY_CONFIGURE; } else { # We do support intra-installation uninstalls. my $uninstall_link = INSTALL::query::user ("Would you like to uninstall the currently linked server", "terminal_mark=?", "y", "default=n"); if ($uninstall_link eq "y") { if (not uninstall($pServerHash->{engine_dir})) { return(undef); } } else { goto RETRY_CONFIGURE; } } } INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Verification", "Setup has automatically detected the following information about the ". "Web server you selected on the previous screen. If the information ". "is correct, type 'y' and press Enter. If the information is incorrect ". "type 'n', press Enter, and then select 'Specify the Web server' from the ". "menu.\n". " \n". "Web server information:\n". " Main configuration file: $pServerHash->{webserver_conf}\n". " Binary: $pServerHash->{webserver_binary}\n". " Version: $pServerHash->{webserver_version}\n". " Type: $pServerHash->{webserver_name}\n". " Port: $pServerHash->{webserver_port}\n". " Root: $pServerHash->{webserver_root}\n" ); my $confirm_install = INSTALL::query::user ("The Web server information is correct","terminal_mark=.", "y","default=n"); if ($confirm_install eq "n") { goto RETRY_CONFIGURE; } my $webserver_note; if (length($pServerHash->{webserver_note})) { $webserver_note = " \nWeb server note:\n".headerize(" ",split(/\n/,$pServerHash->{webserver_note})); } my $virtual_hosts; if (length($pServerHash->{webserver_vhosts})) { $virtual_hosts = " \n Affected vhosts:\n".headerize(" ",split(/\n/,$pServerHash->{webserver_vhosts})); } if ($webserver_note || $virtual_hosts) { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Verification", "A possible issue has been found with your web server configuration. ". "These issues are listed below.\n". $virtual_hosts.$webserver_note); $confirm_install = INSTALL::query::user ("Do you wish to proceed with these settings","terminal_mark=.", "y","default=n"); } if ($confirm_install eq "n") { goto RETRY_CONFIGURE; } my $install_defaults; $install_defaults = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Server Configuration", "Setup will now configure the Sun Chili!Soft ASP Server. Unless you are an ". "experienced Sun Chili!Soft ASP user, it is strongly recommended that you use ". "the default configuration settings (option 1, below). If you choose the ". "custom configuration option, you will be asked to specify a number of ". "settings. For detailed information about configuring Sun Chili!Soft ASP, ". "see 'Chapter 3' in the product documentation.", "Select a configuration option", "terminal_mark=.", "default=Default configuration.", "Customize configuration.", "Choose another Web server to install to."); if ($install_defaults == 2) { $pParameters->{custom_install} = "true"; } elsif ($install_defaults == 3) { goto RETRY_CONFIGURE; } return($pServerHash); } } #============================================================================== # Implementors note: # (1) It is assumed that the caspeng module provides both a configure and # uninstall script, which will handle the installation and removal of # a server installation. #------------------------------------------------------------------------------ sub configure { my $pServerStats; if (interactive) { $pServerStats = interactive_configure; } else { if (exists $pParameters->{webserver_path}) { my $conf_path = $pParameters->{webserver_path}; my %servers = locate_server(dirname($conf_path)); cache_servers(%servers); my $quoted_conf_path = quotemeta($conf_path); foreach(list_servers) { if (m@$quoted_conf_path@) { $pServerStats = load_server($_); last; } } } elsif (exists $pParameters->{webserver_conf}) { my $conf = $pParameters->{webserver_conf}; if (grep { $conf eq $_ } list_servers) { recache_servers($conf); } else { cache_servers(locate_server(dirname($conf))); } $pServerStats = load_server($conf); } else { die("Either the webserver_conf or webserver_path variable must be specified on\n". "the command line in non_interactive mode."); } if (not keys %$pServerStats) { return(error("Unable to find a webserver in the specified webserver_path / webserver_conf:", " $pParameters->{webserver_path} / $pParameters->{webserver_path}")); } elsif (not interactive) { my %server_map = generate_server_map; if (exists $server_map{$pServerStats->{webserver_conf}}) { my $pCrossLinked = $server_map{$pServerStats->{webserver_conf}}; # Check to see if the server is a local cross link if ($pCrossLinked->{engine_dir} eq "$pGlobals->{asphome}/$pCrossLinked->{engine_name}") { if (boolean_value($pParameters->{webserver_overwrite})) { uninstall($pCrossLinked->{engine_dir}); } else { return(error("This Web server is already linked to by another ASP server", "in this installation:", " $pCrossLinked->{engine_dir}"), note("If you would like to override this existing installation, pass ", "'webserver_overwrite=true' as an additional command-line argument.")); } } else { # Error out immediately if the cross link is of global / external type. return(error("This Web server is already linked to by another Sun Chili!Soft ASP installation.", "You may not install to a Web server that is already linked to by another", "installation.", "The installation currently containing this link is:", " $pCrossLinked->{engine_dir}")); } } } } my $result = undef; if (keys %$pServerStats) { if (INSTALL::caspeng::configure($pServerStats)) { my $type = $pServerStats->{webserver_type}; my $method = "INSTALL::${type}::configure"; if (defined &$method) { $result = &$method($pServerStats); $result || INSTALL::caspeng::uninstall($pServerStats); } else { $result = error("Unable to locate a module correlating to $pServerStats->{webserver_type}."); } } else { $result = error("Unable to generate an ASP engine to be linked to the specified Web server."); } } if ($result) { ########## Update the installed_db. my $pIni = INSTALL::ini::open($pGlobals->{installed_db}); if (!$pIni) { error("Could not open $pGlobals->{installed_db}."); INSTALL::caspeng::uninstall($pServerStats); return($result); } my $pSection = INSTALL::ini::insertSection($pIni, $pServerStats->{engine_dir}); if (!$pSection) { error("Could not add section $pServerStats->{engine_dir} to $pGlobals->{installed_db}."); INSTALL::caspeng::uninstall($pServerStats); return($result); } foreach my $key (keys %$pServerStats) { $pSection->{$key} = $pServerStats->{$key}; } $result &= INSTALL::ini::save($pIni, $pGlobals->{installed_db}); } # Don't persist the custom_install flag. delete $pParameters->{custom_install}; return($result); } #------------------------------------------------------------------------------ # This method queries the user for which server they want to reconfigure (of # those listed in the installed_db). If there are none in the cache,then this # method will refer to the configure routine to add a new engine. # # Once the engine to be re-configured is selected by the user, now we again # query the user for which server they want to install to (of those listed # in the webserver cache). If there are none in the cache, and they choose # unlisted, the unlisted server will be checked for existance prior to # installation. #============================================================================== # Implementors note: # (1) Each webserver pm is assumed to have a configure method which will take # a hash as a parameter and use the information contained in that hash # to configure a server. This method should return undef upon failure, # non-undef on success. #============================================================================== sub interactive_reconfigure { my $pCurEngineStats; # Interactive Re-Configuration, where the engines have not been specified: # We need to get the engine location from the user. my @servers = &load_used_servers; my @options; my $chosen_default; if (@servers) { foreach my $pServerStats (@servers) { my $tense = ($pServerStats->{webserver_name} =~ /^[aeiouh]/i) ? 'an' : 'a'; my $server_string = ( "$pServerStats->{engine_name} (Associated with $tense $pServerStats->{webserver_name} Web server):\n". " Web Server conf file: $pServerStats->{webserver_conf}\n". " Web Server port number: $pServerStats->{webserver_port}\n" ); push @options,$server_string; } } else { # No Engines are available for configuration. # Lead the user for adding a new configuration. INSTALL::query::user_menu ("Sun Chili!Soft ASP - Server Reconfiguration.", "There are no ASP instances installed to reconfigure. Perhaps you meant ". "add-server?" ); return (undef); } #--------------------------------------------------------------------------- # If only 1 webserver-to-asp link exists, implicitly choose that one. # Otherwise, query the user for which they would like to reconfigure. #--------------------------------------------------------------------------- my $server_no = undef; my $max_options = @options; # Sriram - I am presently commenting this below mentioned feature for # simplicity and compatiblity sake. # if ($max_options == 1) { # $server_no = $max_options; # } # else { QUERY_FOR_ENGINE_INFO: $server_no = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Server Reconfiguration", "From the following list, select the ASP Server whose Web server linkage you ". "want to change. If you do not want to make any changes at this time, ". "press Enter to cancel the reconfiguration.", "Select the ASP Server you want to reconfigure", @options, "default=Cancel." ); # } if ($server_no <= $max_options) { $pCurEngineStats = $servers[$server_no - 1]; INSTALL::query::user_menu ( "Sun Chili!Soft ASP - Server Reconfiguration", "Confirm that the information below accurately represents the Web server-to-ASP ". "Server linkage that you want to change. By answering 'y' (yes) to the question below, ". "you are specifying that any subsequent Web server selection will replace this ". "association. If this is not what you want, type 'n' (no).\n". " \n". "ASP server information:\n". " ASP server directory: $pCurEngineStats->{engine_dir}\n". " \n ". "Associated Web server information:\n". " Main configuration file: $pCurEngineStats->{webserver_conf}\n". " Binary: $pCurEngineStats->{webserver_binary}\n". " Version: $pCurEngineStats->{webserver_version}\n". " Type: $pCurEngineStats->{webserver_name}\n". " Port: $pCurEngineStats->{webserver_port}\n", ); my $answer = INSTALL::query::user ( "Is this information correct", "terminal_mark=?", "y", "default=n" ); if ($answer eq "n") { goto QUERY_FOR_ENGINE_INFO; } } else { return(undef); } my @server_list; RETRY_RECONFIGURE: recache_servers(list_servers); my @pServerHashes = load_server_links; my @webserver_options = (); my @pUnusedServers = (); foreach my $pServerHash (@pServerHashes) { my $server_text; if (boolean_value($pServerHash->{webserver_bundled})) { $server_text .= "Bundled "; } $server_text .= $pServerHash->{webserver_name}; if (boolean_value($pServerHash->{webserver_https})) { $server_text .= " Secure Server"; } else { $server_text .= " Web server"; } unless(exists $pServerHash->{engine_dir}) { $server_text .= " ($pServerHash->{webserver_conf})"; push @webserver_options, "$server_text."; push @pUnusedServers,$pServerHash; } } my $index; { $index = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Server Reconfiguration", "From the following list, select the Web server that you want ". "to associate the depicted ASP server with. If the Web server is not ". "listed below, you may choose to either specify this Web server manually or ". "attempt to auto-detect it. (Note: The Web server list will not include ". "Web servers that are currently linked with other Sun Chili!Soft ASP ". "installations.) If you want to cancel this entire operation, choose 'Do ". "not configure a Web server.'\n". " \n". "ASP server information:\n". " ASP server directory: $pCurEngineStats->{engine_dir}", "Which Web server would you like to reassociate with", "terminal_mark=?", @webserver_options, "Specify the Web server.", "Attempt to auto-detect more Web servers.", "default=Do not configure a Web server.", ); } print "\n"; if ($index == (@webserver_options + 1)) { configure_unlisted; goto RETRY_RECONFIGURE; } elsif ($index == (@webserver_options + 2)) { build_server_cache; goto RETRY_RECONFIGURE; } elsif ($index == (@webserver_options + 3)) { goto QUERY_FOR_ENGINE_INFO; } else { $index--; my $pServerHash = $pUnusedServers[$index]; INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Verification", "Setup has automatically detected the following information about the Web server you ". "selected on the previous screen. Please make sure all of the ". "information is correct. If it is correct, type Y, and then press Enter. ". "If it is not correct, type N, press Enter, and select 'Specify the Web server' ". "from the user menu.". " \n". " \n". "Web server information:\n". " Main configuration file: $pServerHash->{webserver_conf}\n". " Binary: $pServerHash->{webserver_binary}\n". " Version: $pServerHash->{webserver_version}\n". " Type: $pServerHash->{webserver_name}\n". " Port: $pServerHash->{webserver_port}\n". " Root: $pServerHash->{webserver_root}\n" ); my $confirm_install = INSTALL::query::user ("The Web server information is correct","terminal_mark=.", "y","default=n"); if ($confirm_install eq "n") { goto RETRY_RECONFIGURE; } my $webserver_note; if (length($pServerHash->{webserver_note})) { $webserver_note = " \nWeb server note:\n".headerize(" ",split(/\n/,$pServerHash->{webserver_note})); } my $virtual_hosts; if (length($pServerHash->{webserver_vhosts})) { $virtual_hosts = " \n Affected vhosts:\n".headerize(" ",split(/\n/,$pServerHash->{webserver_vhosts})); } if ($webserver_note || $virtual_hosts) { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Verification", "A possible issue has been found with your web server configuration.\n". $virtual_hosts.$webserver_note); $confirm_install = INSTALL::query::user ("Do you wish to proceed with these settings","terminal_mark=.", "y","default=n"); } if ($confirm_install eq "n") { goto RETRY_CONFIGURE; } my $install_defaults; $install_defaults = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Server Reconfiguration", "Setup will now reconfigure your Sun Chili!Soft ASP server to Web server ". "association. Any current association will be subsequently lost, disabling the ". "previously associated Web server from serving up ASP content. If you do not ". "want this action to be performed, select 'Choose another Web server to install ". "to' from the options listed below. If you want to proceed, you have two ". "different paths to choose from. Unless you are an experienced Sun Chili!Soft ". "ASP user, it is highly recommended that you choose the default configuration ". "path. If you choose the custom configuration path, you will be asked to specify ". "a number of configuration settings along the way. For more information about ". "configuring Sun Chili!Soft ASP installations, see the README file or the ". "online product documentation for more details.\n". " \n". "Note: If reconfiguration fails, for any reason, the current association\n". " will be left unchanged.", "Select a configuration option", "terminal_mark=.", "default=Default configuration.", "Customize configuration.", "Choose another Web server to install to."); if ($install_defaults == 2) { $pParameters->{custom_install} = "true"; } elsif ($install_defaults == 3) { goto RETRY_RECONFIGURE; } return ($pServerHash,$pCurEngineStats); } return (undef); } #============================================================================== # Implementors note: #============================================================================== # These are the following jobs, this routine is supposed to do. # For Non-Interactive :- # 1. validate the parameters. # 2. the parameters should have something like this - # valid engine name, and the new webserver configuration file. # 3. check whether the new webserver is linked to any existing # chiliasp. # 4. If yes, say the error to the user. # 5. if no, do the following steps. # 5-a. configure the new webserver and webserver-cache file. # 5-b. update the .installed_db # 5-c. remove the entries from the current webserver conf files. # 5-d. remove the current entries from the .installed_db file. # For interactive :- # 1. show the list of currently installed asp engine locations. # 2. ask the user to choose one of the current asp engines to reconfigure. # 3. ask the user for the new webserver configuration location. # 4. the item in no.3 should behave like that of interactive configure. # 5. get the web server configuration. # 5-a. configure the new webserver and webserver-cache file. # 5-b. update the .installed_db # 5-c. remove the entries from the current webserver conf files. # 5-d. remove the current entries from the .installed_db file. #============================================================================== sub reconfigure { # if we enter this routine, without any installed ASP Engines, then route # them accordingly to configure a new web server and ASP engine. my @servers = &load_used_servers; my $num_server = @servers; if (! $num_server) { return (&configure); } # use this structure to store reconfigured server statistics. my $result = undef; my $pServerStats; my $pCurEngineStats; # this is supposed to contain the information on current engine. if (interactive) { # this routine is supposed to return a hash table containing # new webserver configuration informations and current ASP Engine # configuration informations. ($pServerStats,$pCurEngineStats) = &interactive_reconfigure; if (keys %{$pServerStats} && keys %{$pCurEngineStats}) { foreach (keys %$pCurEngineStats) { ($pServerStats->{$_} = $pCurEngineStats->{$_}) unless /^webserver/; } } else { return (undef); } } else { # validate the engine parameter. my @servers = &load_used_servers; my %engineStats = map{$_ => $pParameters->{$_}} grep { /^engine/ } keys %{$pParameters}; if (not keys %engineStats) { error("Your input parameters are either invalid or NOT specified.", "You will need to specify the engine name or engine location as input parameter."); return (undef); } foreach my $pListEngine (@servers) { foreach my $key (keys %engineStats) { if (($engineStats{$key} eq $pListEngine->{engine_dir}) || ($engineStats{$key} eq $pListEngine->{engine_name})) { $pCurEngineStats = $pListEngine; last; } } } if (keys %$pCurEngineStats && exists $pCurEngineStats->{engine_dir}) { # and Load the current engine related entries from this engine configurations. foreach (keys %$pCurEngineStats) { ($pServerStats->{$_} = $pCurEngineStats->{$_}) unless /^webserver/; } } else { error ("Unable to validate ASP engine installation location."); note(%engineStats); return (undef); } # now validate the webserver related parameters. my $pWebServerStats; recache_servers(list_servers); if (exists $pParameters->{webserver_path}) { my $conf_path = $pParameters->{webserver_path}; my %servers = locate_server(dirname($conf_path)); cache_servers(%servers); my $quoted_conf_path = quotemeta($conf_path); foreach (list_servers) { if (m@$quoted_conf_path@) { $pWebServerStats = load_server($_); last; } } } elsif (exists $pParameters->{webserver_conf}) { my $conf = $pParameters->{webserver_conf}; if (grep { $conf eq $_ } list_servers) { recache_servers($conf); } else { cache_servers(locate_server(dirname($conf))); } $pWebServerStats = load_server($conf); } else { # probably an invalid parameter here. error("Input parameter is either invalid or NOT specified."); return (undef); } if (not keys %$pWebServerStats) { # probably an invalid parameter here. error("Unable to find a Web server in the specified webserver_path / webserver_conf:", " $pParameters->{webserver_path} / $pParameters->{webserver_path}"); error("Input parameter is either invalid or NOT specified."); return (undef); } # now we need to make sure that this webserver_conf file is not a cross linked one. my %server_map = generate_server_map; if (exists $server_map{$pWebServerStats->{webserver_conf}}) { my $pCrossLinked = $server_map{$pWebServerStats->{webserver_conf}}; if ($pCrossLinked->{engine_dir} eq $pCurEngineStats->{engine_dir}) { note("The Web server is already linked to that ASP server."); return(1); } # Check to see if the server is a local cross link if ($pCrossLinked->{engine_dir} eq "$pGlobals->{asphome}/$pCrossLinked->{engine_name}") { # Now before you uninstall this installation make sure that the user really wants us to # to do this one. if (boolean_value($pParameters->{webserver_overwrite})) { uninstall($pCrossLinked->{engine_dir}); } else { return(error("This Web server is already linked to by another ASP server", "in this installation:", " $pCrossLinked->{engine_dir}"), note("If you would like to override (ie. uninstall) this existing installation, ", "pass 'webserver_overwrite=true' as an additional command-line argument.")); } } else { # Error out immediately if the cross link is of global / external type. return(error("This Web server is already linked to by another ASP installation.", "You may not reconfigure to a Web server that is already linked to by another", "installation.", "The installation directory currently containing this link is:", " $pCrossLinked->{engine_dir}")); } } foreach (keys %$pWebServerStats) { $pServerStats->{$_} = $pWebServerStats->{$_}; } } if (not exists $pServerStats->{webserver_type}) { error("'webserver::reconfigure' Failed: unable to detect Web Server type. "); return (undef); } # Now we need to configure the new web server. my $new_webserver_type = $pServerStats->{webserver_type}; my $new_webserver_installMethod = "INSTALL::${new_webserver_type}::configure"; my $new_webserver_uninstallMethod = "INSTALL::${new_webserver_type}::uninstall"; if (defined &$new_webserver_installMethod) { $result = &$new_webserver_installMethod($pServerStats); } if (! $result) { error("Error occured while configuring the new Web server.", "Unable to locate or execute a module correlating to $pServerStats->{webserver_type}."); return (undef); } summary_log ("Server reconfigured ($pServerStats->{engine_name}):", " Associated Web Server conf file: $pServerStats->{webserver_conf}", " Associated Web Server port: $pServerStats->{webserver_port}", " Location: $pServerStats->{engine_dir}", " Port: $pServerStats->{engine_port}" ); # now we have got the new Web server working.So time to clean out the old ASP Server. # If we are not able to remove the old ASP Server, then we should clean out the new one # and get out without touching anything else. my $old_webserver_type = $pCurEngineStats->{webserver_type}; my $old_websever_uninstallMethod = "INSTALL::${old_webserver_type}::uninstall"; # A small hack to avoid asking the user from restarting the old Web Server. if ( not exists $pParameters->{webserver_restart} ) { $pParameters->{webserver_restart} = 1; } # now make sure that we have the engine start and stop scripts available. # we need this to restart our ASP Engines. # Restart ASP now? my $start_asp = 1; if (exists $pParameters->{start_asp}) { $start_asp = boolean_value($pParameters->{start_asp}); } # elsif (interactive) { # $start_asp = INSTALL::query::boolean_default ( "Would you like to start this Chili!Soft ASP server",$start_asp); # } if ($start_asp) { my $pIniSectionRef = INSTALL::caspeng::get_pSection_Installeddb("engine_name",$pServerStats->{engine_name}); if (! $pIniSectionRef) { error("Unable to lookup engine name=$pServerStats->{engine_name} from .installed_db file"); note("You will need to manually restart your ASP Engine for the new settings to take effect."); } else { if (interactive) { print STDERR ("Restarting the ASP server ($pServerStats->{engine_name}) ... "); } my $pid = fork; unless($pid) { my $result = INSTALL::caspeng::restart_engine($pIniSectionRef); if (not $result) { error("Error occurred while trying to restart your engine."); note("You will need to manually restart your ASP Engine for the new settings to take effect."); } exit(0); } else { if (interactive) { INSTALL::common::spinner_wait($pid); print STDERR ("\n"); } else { waitpid $pid, 0; } } } } # Load the entries from .installed_db file my $pIni = INSTALL::ini::open($pGlobals->{installed_db}); if (!$pIni) { error("Could not open $pGlobals->{installed_db}."); error (" Web server re-configure routine Failed."); return(undef); } my $pSection = INSTALL::ini::openSection($pIni,$pServerStats->{engine_dir}); # Now save this reconfigured server statistics. %{$pSection} = map {$_ => $pServerStats->{$_}} keys %{$pServerStats}; # We need some sort of backup before modifying this file as this way. $result = INSTALL::ini::save($pIni, $pGlobals->{installed_db}); # Don't persist the custom_install flag. delete $pParameters->{custom_install}; unless (&$old_websever_uninstallMethod ($pCurEngineStats)) { # Now fold back all the changes. error("Completed with errors.", "Error occured while trying to unlink to old web server."); note("You will need to manually remove the Sun Chili!Soft Asp entries from ", "your old web server configuration files."); return (undef); } return ($result); } #------------------------------------------------------------------------------ # This method returns a list of references to all used servers. Each servers # information is placed into the returned list as a reference to a hash. #------------------------------------------------------------------------------ sub load_used_servers { my $pIni = INSTALL::ini::open($pGlobals->{installed_db}); if (not $pIni) { return(error("Could not open $pGlobals->{installed_db}.")); } my @section_list = INSTALL::ini::getSectionNames($pIni); my @result; foreach(@section_list) { my $pSection = INSTALL::ini::openSection($pIni,$_); my %server_details = %{$pSection}; if (keys %server_details) { push @result,\%server_details; } } return(@result); } #------------------------------------------------------------------------------ # This method is similar to load_used_servers, except that it merely returns # a list of configuration files instead. #------------------------------------------------------------------------------ sub list_used_servers { ($#_ < 0) || die "Invalid number of arguments to list_servers."; return(map {$_->{webserver_conf}} load_used_servers); } #------------------------------------------------------------------------------ # This method queries the user for which server they want to uninstall (of # those listed in the installed_db). If there are none in the cache, this # method will merely return success (ie. non-undef). The optional arguments # are the specific list of engine directories to uninstall. # # Note: This method is a general means of also removing the asp-engine which # is serving that webserver. #============================================================================== # Implementors note: # (1) Each webserver pm is assumed to have an uninstall method which will take # a hash as a parameter and use the information contained in that hash # to uninstall that server. This method should return undef upon failure, # non-undef on success. It should be noted that this method is responsible # for also invoking caspeng::uninstall, with the appropriate information. # (2) This method assumes that the caspeng module has an uninstall method which # takes the information of a webserver-to-asp link, and properly removes # itself. #------------------------------------------------------------------------------ sub interactive_uninstall { my @params = @_; my @servers = load_used_servers; my @uninstall_list; if (@params) { my %server_hash = map(($_=>undef),@params); foreach my $pServerStats (@servers) { if (exists $server_hash{$pServerStats->{engine_dir}}) { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Uninstall", "You have selected to uninstall an ASP-to-webserver association. ". "The details specific to this association are the following:\n". " \n". " ASP Server dir: $pServerStats->{engine_dir}\n". " Web server type: $pServerStats->{webserver_name}\n". " Settings file: $pServerStats->{webserver_conf}\n". " Port: $pServerStats->{webserver_port}\n" ); report("Warning: ", "You are about to uninstall the engine $pServerStats->{engine_name}."); my $answer = INSTALL::query::user ("Do you want to continue","terminal_mark=?","y","default=n"); if ($answer eq "y") { push @uninstall_list,$pServerStats; } } } return(@uninstall_list); } else { # Interactive Uninstall, where the engines have not been specified: my @options; my $chosen_default; if (@servers) { foreach my $pServerStats (@servers) { my $server_string = ("$pServerStats->{engine_dir}\n". " Web server type: $pServerStats->{webserver_name}\n". " Settings file: $pServerStats->{webserver_conf}\n". " Port: $pServerStats->{webserver_port}\n" ); push @options,$server_string; } } else { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Uninstall", "No ASP-to-Webserver associations exist."); return(); } my $max_options = @options; RETRY_UNINSTALL_QUERY: my $server_no = INSTALL::query::user_menu ("Sun Chili!Soft ASP - Web Server Uninstall", "By uninstalling a Sun Chili!Soft ASP Server, you will be disabling the ". "currently associated Web server from serving up ASP content. Any data ". "contained under the specified engine directory will be removed along ". "with the ASP Server.", "Select the ASP Server you want to uninstall", @options, "Uninstall all engines.", "default=Cancel uninstall."); if ($server_no <= $max_options) { report("Warning: ", "You are about to uninstall the engine $servers[$server_no - 1]->{engine_name}."); my $answer = INSTALL::query::user ("Do you want to continue","terminal_mark=?","y","default=n"); if ($answer eq "n") { goto RETRY_UNINSTALL_QUERY; } push @uninstall_list,$servers[$server_no - 1]; } elsif ($server_no == ($max_options + 1)) { report("Warning: ","You are about to uninstall all engine associations."); my $answer = INSTALL::query::user ("Do you want to continue","terminal_mark=?","y","default=n"); if ($answer eq "n") { goto RETRY_UNINSTALL_QUERY; } @uninstall_list = @servers; } else { return(); } return(@uninstall_list); } } sub uninstall { my @params = @_; my @uninstall_list; RETRY_UNINSTALL: if (interactive) { @uninstall_list = interactive_uninstall(@params); } elsif (@params) { my @servers = load_used_servers; my %server_hash = map(($_=>undef),@params); foreach my $pServerStats (@servers) { if (exists $server_hash{$pServerStats->{engine_dir}}) { push @uninstall_list, $pServerStats; } } } else { return(undef); } my $total_result = 1; foreach my $pServerStats (@uninstall_list) { my $result; if (INSTALL::caspeng::uninstall($pServerStats)) { $result = 2; } my $method = "INSTALL::$pServerStats->{webserver_type}::uninstall"; if (defined &$method) { unless (&$method($pServerStats)) { error("Failed to uninstall $pServerStats->{engine_name}."); print STDERR "Press enter to continue ..."; ; #goto RETRY_UNINSTALL; $total_result = 0; } else { $result |= 1; } } else { return(error("Unable to locate a module correlating to $pServerStats->{webserver_type}.")); } if (interactive) { if ($result == 3) { report("Status: The uninstall was successful."); } elsif ($result == 2) { report("Status: ", "The Web server failed to uninstall.", "The engine linked to that Web server was sucessfully uninstalled."); } elsif ($result == 1) { report("Status: ", "The Web server was sucessfully uninstalled.", "The engine linked to that Web server failed to uninstall."); } else { report("Status: The uninstall failed."); } } } return($total_result && @uninstall_list); } 1;