package INSTALL::netscape; use INSTALL::common; use INSTALL::os; use INSTALL::query; use INSTALL::chiliXML ; use strict; my $debug = 0; # this is the constant flag, we need to use, if we decide to support # version dependent netscape modules. If we support version dependent # netscape modules, then there needs to be a corresponding # netscape_versions in the module directory. # if this flag is set to Zero, we assume that there will be a directory # called netscape under the modules directory,without any versions. # if this flag is set to 1, then we will expect a modules directory # with versions informations. If in case, we are not able to find # a corresponding modules directory, then we will use the generic # modules folder. my $CONST_UseNetscapeVersions = 1; my $CONST_NetscapeGenericMinorVersion = "x" ; my $pGlobals = \%INSTALL::global::variables; my $pParameters = \%INSTALL::parameter::variables; my $pOS = \%INSTALL::os::Details; #------------------------------------------------------------------------------ # This is a global hash table to store the configuration informations # for a Netscape 6 server. This hash table has been constructed to avoid # executing the time-consuming XML-Parser and its related routines. # This hash table data structure info is described below for future # reference. # key is 'netscape configuration file ( for eg. obj.conf ). # to keep the key unique, we need to store the absolute file name here. # and value is the REFERENCE TO A ARRAY of 'virutal Server' Informations # for eg :- # pNS6ServerInfo->{"/usr/iplanet/servers/https-s1/config/obj.conf"} => # A1(@Ref), where A1 can be further decomposed as # A1 = [ [ [VHOST_ATTR] ], [VHOST_ATTR] ] ] # where, VHOST_ATTR = [ PORT, MIME_TYPE, VHOST_NAME ] # #------------------------------------------------------------------------------ my %netscape6ServerInfo = (); my $pNS6ServerInfo = \%netscape6ServerInfo ; #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # External functions #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ #------------------------------------------------------------------------------ # This method attempts to find a Netscape server located in the directory # specified. It does this by checking for an magnus.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."; sub isDir { ($#_ == 0) || die "Invalid number of arguments."; my ($dir) = @_; return((-d $dir) && (not -l $dir)); } my ($server_path) = @_; # look for Netscape servers. if (($server_path !~ m@/admin-serv@i) && ($server_path !~ m@/http[sd]-admserv@i) && isDir("$server_path/config") && (-f "$server_path/config/magnus.conf")) { if (($server_path !~ /ns-config/) && ($server_path !~ /zeus/i)) { return("$server_path/config/magnus.conf"); } else { return(); } } elsif (($server_path !~ /(\S+)\/admin-serv(.*)/i) && ($server_path !~ /(\S+)\/http[sd]-admserv(.*)/i) && ($server_path !~ m@/conf_bk@) && (-f "$server_path/magnus.conf")) { # Detect Zeus, as accurately as possible. my @server_components = split(m@/@,$server_path); my @server_paths; for(my $i=0; $i < @server_components; $i++) { push @server_paths,join('/',@server_components[0..$i]); } foreach my $server_path (@server_paths) { if ((-d "$server_path/webadmin") || (-d "$server_path/ns-config")) { # The server is zeus, ignore. return(); } } return("$server_path/magnus.conf"); } else { # Make sure we match a subdirectory with the name netscape in it, for # completeness. local *ROOT; if (opendir(ROOT,"$server_path")) { my @subfiles = grep { $_ ne "." && $_ ne ".." } readdir(ROOT); closedir(ROOT); my @result; foreach (@subfiles) { if (isDir("$server_path/$_") && ( # This which should logically cause a recursion. (-d "$server_path/config") || (/^http[ds]-/) || (/iplanet/i) || (/netscape/i) || (/servers/i) || (/server4/i) ) ) { push @result,locate_server("$server_path/$_"); } } return(@result); } } return(); } #------------------------------------------------------------------------------ # 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: # conf = # type = netscape sub cache_server { 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 file does not exist or is not executable."); report(""); } return(-x $file); } # Start of Cache Server Starts here. ($#_ == 0) || die "Invalid number of arguments to cache_server."; my ($pServerStats) = (@_); my $bin_dir ; my $bin; my $valid_netscape=0; # Default to obj.conf, if not specified. my $obj_conf = "obj.conf"; # Parse the Netscape XML configuration files. my $pNS6XmlServerInfo ; unless (open(CONFIG, "<$pServerStats->{webserver_conf}")) { return(error("Could not open $pServerStats->{webserver_conf} - cache_server.")); } # Make sure that the separate entry called magnus.conf exists in the # .installed_db file. if (not exists $pServerStats->{webserver_magnus_conf}) { $pServerStats->{webserver_magnus_conf} = $pServerStats->{webserver_conf} ; } while () { if (/^\s*LoadObjects\s(.*)/i) { $obj_conf = $1; } elsif (/^\s*\#ServerRoot\s+(\S+)/) { $pServerStats->{webserver_server_root} = $1; $pServerStats->{webserver_root} = $1; $pServerStats->{webserver_root} =~ s/(\S.*)\/(\S+)$/$1/ ; } elsif (/^\s*ServerName\s+(\S+)/) { $pServerStats->{webserver_realhost} = $1; } elsif (/^\s*Port\s+([0-9]+)/) { $pServerStats->{webserver_port} = $1; } last if ( $pServerStats->{webserver_root} && $pServerStats->{webserver_realhost} && $pServerStats->{webserver_port} ); } close(CONFIG); my $absolute_objconf; if ($obj_conf =~ /^\//) { $absolute_objconf = $obj_conf; } else { $absolute_objconf = "$pServerStats->{webserver_conf}"; $absolute_objconf =~ s/(.*)magnus.conf(.*)$/$1/; $absolute_objconf .= $obj_conf; } $pServerStats->{webserver_obj_conf} = $absolute_objconf; ## Update the mime.types file to refer to the appropriate locations. unless (open(IN, "<$pServerStats->{webserver_obj_conf}")) { return(error("Could not load Object Configuration file")); } close(IN); ### Look for a server.xml file which should be in the same ### location as that of obj.conf file. ### We need to parse this file for collecting more informations ### about this server. This will be available only from ### Netscape 6. my $server_xml = undef; if ( -f "$pServerStats->{webserver_server_root}/config/server.xml") { $server_xml = "$pServerStats->{webserver_server_root}/config/server.xml"; } elsif ( -f "$pServerStats->{webserver_server_root}/server.xml") { $server_xml = "$pServerStats->{webserver_server_root}/server.xml"; } if (-f $server_xml) { # this refers to version Netscape 6, parse the XML file. # this routine parses the XML Configuration file and stores the information # in the global hash table called $pNS6ServerInfo. unless (&process_NS6XmlTags($server_xml)) { error ("Error in cache-server:Error in parsing the Netscape XML Configuration file"); return (undef); } # Now that we have parsed the information, we need to retrieve the real host server # configuration information. my $pVsServerInfo ; unless ($pVsServerInfo = retrieve_NS6ServerInfo("realhost",$pServerStats->{'webserver_obj_conf'})) { error ("Error in cache-server: Error in retrieving RealHost Information from Netscape XML Configuration file"); return (undef); } # at this point we are interesting in retrieving the list if (exists $pVsServerInfo->{"port"}) { $pServerStats->{webserver_port} = $pVsServerInfo->{"port"} ; } if (exists $pVsServerInfo->{"vhost"}) { $pServerStats->{webserver_vhost} = $pVsServerInfo->{"vhost"} ; } if (exists $pVsServerInfo->{"mime"}) { my $mime_types = $pVsServerInfo->{"mime"} ; my $absolute_mime= undef; if ($mime_types =~ /^\//) { $absolute_mime = $mime_types; } else { $absolute_mime = "$pServerStats->{webserver_conf}"; $absolute_mime =~ s/(.*)magnus.conf(.*)$/$1/; $absolute_mime .= $mime_types; } $pServerStats->{webserver_mime_types} = $absolute_mime; } #### #### #foreach (keys %{$pVsServerInfo}) { # if (exists $pVsServerInfo->{$_}) { # my $newkey = "webserver_" ; # $newkey .= "$_" ; # $pServerStats->{$newkey} = $pVsServerInfo->{$_} ; #### # if ($debug) { # open(DEBUG_LOG,">>$pGlobals->{log_dir}/netscape_debug.log"); # print DEBUG_LOG "key is $_ => $pServerStats->{$newkey}\n"; # close(DEBUG_LOG); # } # } # } #### #### } # Not serious enough to quit ??? if (not $pServerStats->{webserver_port}) { report_log("Warning: ", "Unable to find the Web server port information for the", "configuration file (specified below): ", " $pServerStats->{webserver_conf}"); } # If mime.types file does not exist add it here. if (not exists $pServerStats->{webserver_mime_types} ) { ## Update the mime.types file to refer to the appropriate locations. unless (open(IN, "<$pServerStats->{webserver_obj_conf}")) { return(error("Could not load Object Configuration file")); } my $mime_types = "mime.types"; # Default to mime.types, if not specified. while () { if (/Init\sfn=("?)load-types\1\smime-types=("?)(.*)(\2)/i) { $mime_types = $3; last ; } } close(IN); my $absolute_mime=' '; if ($mime_types =~ /^\//) { $absolute_mime = $mime_types; } else { $absolute_mime = "$pServerStats->{webserver_conf}"; $absolute_mime =~ s/(.*)magnus.conf(.*)$/$1/; $absolute_mime .= $mime_types; } $pServerStats->{webserver_mime_types} = $absolute_mime; } # Make sure we have a valid mime types file here. unless (open(IN, "<$pServerStats->{webserver_mime_types}")) { return(error("Could not open $pServerStats->{webserver_mime_types}")); } close(IN); if (not exists $pServerStats->{webserver_binary}) { if ((exists $pParameters->{webserver_binary}) && ($pParameters->{webserver_binary} =~ /ns-http/i)) { $pServerStats->{webserver_binary} = $pParameters->{webserver_binary}; $bin_dir = dirname($pParameters->{webserver_binary}); $bin = basename($pParameters->{webserver_binary}); } elsif ((-d "$pServerStats->{webserver_root}/bin/https") && (-r "$pServerStats->{webserver_root}/bin/https/ns-httpd")) { $pServerStats->{webserver_binary} = "$pServerStats->{webserver_root}/bin/https/ns-httpd"; $bin_dir = "$pServerStats->{webserver_root}/bin/https"; $bin = "ns-httpd"; } elsif ((-d "$pServerStats->{webserver_root}/bin/https/bin") && (-r "$pServerStats->{webserver_root}/bin/https/bin/ns-httpd")) { $pServerStats->{webserver_binary} = "$pServerStats->{webserver_root}/bin/https/bin/ns-httpd"; $bin_dir = "$pServerStats->{webserver_root}/bin/https/bin"; $bin = "ns-httpd"; } } else { $bin_dir = dirname($pServerStats->{webserver_binary}); $bin = basename($pServerStats->{webserver_binary}); } # Remove any "" encapsulation. foreach (keys %{$pServerStats}) { $pServerStats->{$_} =~ s/\"([^\"]*)\"/$1/; } if ($debug) { trace "bin_dir is $bin_dir \n"; trace "bin is $bin \n"; } use Cwd; if (-x "$bin_dir/$bin") { my $cwd = getcwd(); my $asphome = $pGlobals->{asphome}; $ENV{SERVER_ROOT} = $pServerStats->{webserver_root}; # On HP-UX systems, Netscape binary is dependent on Java library. # So we need to source the lib path for Java Library here. open NETSCAPE_BIN, ". $asphome/INSTALL/templates/netscape.env.sh ; cd $bin_dir;./$bin -v |" or die "Unable to detect the netscape version "; while () { if (/Netscape-Enterprise\/(\d+)\.(\d+)(.*)/i || /WebServer-Enterprise\/(\d+)\.(\d+)(.*)/i) { # 3.6 / 4.0 # 4.1 $pServerStats->{webserver_version} = "$1.$2"; $pServerStats->{webserver_release} = "$1.$2 $3"; $pServerStats->{webserver_major} = $1; $pServerStats->{webserver_minor} = $2; last; } } close(NETSCAPE_BIN); chdir $cwd or die "couldn't change to directory $cwd "; } elsif (not -d "$bin_dir") { return(error_log("Unable to obtain locate netscape server binary directory:", " $bin_dir")); } else { return(error_log("Unable to obtain version values for the server with this Netscape binary:", " $pServerStats->{webserver_binary}")); } if (not exists $pServerStats->{webserver_version}) { error_log("The specified webserver_binary=$pServerStats->{webserver_binary} option", "specifies a binary which does not appear to be a Netscape binary. This", "was detected by running '$pServerStats->{webserver_binary} -v' and not", "receiving a result containing the case-insensitive word 'Netscape'. As", "a result this install will discontinue configuring this webserver, which", "correspond to the configuration file (specified below)", " $pServerStats->{webserver_conf}"); return(undef); } elsif ($pServerStats->{webserver_version} < 4.0) { error_log("Sun Chili!Soft ASP does not support Netscape versions earlier than 4.0.", "One such server was detected with version '$pServerStats->{webserver_version}' at: ", " $pServerStats->{webserver_root}"); return(undef); } ## FIXME,we are yet to add support for Secure Socket Layer webservers $pServerStats->{webserver_https} = "no"; my $start_script; my $stop_script; if (not exists $pServerStats->{webserver_start_script}) { if (not -r "$pServerStats->{webserver_server_root}/start" ) { note("Unable to find the Netscape start script location at $pServerStats->{webserver_server_root}\n"); $start_script = INSTALL::query::user_function ("Input the path and filename of the Netscape server start script\n", *confirm_existence, "default=none", "invalid_choice="); if ($start_script eq "none") { note("Unable to find the Netscape server start script.Skipping this installation.\n"); return (undef); } } else { $start_script="$pServerStats->{webserver_server_root}/start"; } if ( -r "$start_script" ) { $pServerStats->{webserver_start_script}= $start_script; } } if (not exists $pServerStats->{webserver_stop_script}) { if (not -r "$pServerStats->{webserver_server_root}/stop" ) { note("Unable to find the Netscape stop script location at $pServerStats->{webserver_server_root}\n"); $stop_script = INSTALL::query::user_function ("Input the path and filename of the Netscape server stop script\n", *confirm_existence, "default=none", "invalid_choice="); if ($stop_script eq "none") { note ("Unable to find the Netscape server stop script.Skipping this installation.\n"); return (undef); } $pServerStats->{webserver_stop_script} = $stop_script; } else { $pServerStats->{webserver_stop_script}= "$pServerStats->{webserver_server_root}/stop"; } } $pServerStats->{webserver_status_script} = "$pGlobals->{asphome}/INSTALL/netscapectl \"binary=$pServerStats->{webserver_binary}\" ". "\"conf=$pServerStats->{webserver_conf}\" status"; # This webserver is to be identified as a Netscape / iPlanet webserver, # depending on its major version. if ($pServerStats->{webserver_major} >= 6) { $pServerStats->{webserver_name} = 'iPlanet'; } else { $pServerStats->{webserver_name} = 'Netscape'; } return(1); } ################################################## # Start / Stop Netscape rpm on (X) distribution. ################################################## sub restart_netscape { (@_ == 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_netscape { (@_ == 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_netscape { (@_ == 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); } } #------------------------------------------------------------------------------ # This method will ask all of the appropriate questions, to properly configure # an netscape 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. #------------------------------------------------------------------------------ my @CONST_DefaultNetscapeDirs = ( "/usr/iplanet/servers", "/usr/netscape/server4", "/usr/local/netscape/server4", "/usr/netscape", "/usr/local/netscape" ); sub configure_unlisted { sub confirm_valid_netscape { ($#_ == 0) || die "Invalid number of arguments."; my ($dir) = @_; if ($dir 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 -d $dir) { report("Invalid: ","The specified directory does not exist."); report(""); # Cause a requery. return(undef); } elsif (not locate_server($dir)) { report("Invalid: ","Unable to locate any Netscape / iPlanet servers in that directory."); report(""); # Cause requery. return(undef); } return(1); } my ($cache_file) = (@_); CONFIGURE_NETSCAPE: INSTALL::query::user_menu ("Sun Chili!Soft ASP - Netscape / iPlanet Configuration", "To configure Sun Chili!Soft ASP to run with the Netscape / iPlanet ". "Web server, you must enter the root directory of your Web server ". "installation. A typical installation is located at $CONST_DefaultNetscapeDirs[0]. ". "Verify the location of the Web server before proceeding with this ". "configuration.\n". " \n". "Note: To exit out of Web server configuration, type 'none' for the\n". " listed option." ); my $server_rootdir; # Try to pick the appropriate netscape directory, if one can be found, otherwise # rever foreach (@CONST_DefaultNetscapeDirs) { if (-d $_) { $server_rootdir = $_; last; } } if (not $server_rootdir) { $server_rootdir = $CONST_DefaultNetscapeDirs[0]; } $server_rootdir = INSTALL::query::user_function ("Enter the location of your Netscape / iPlanet Web server installation\n", *confirm_valid_netscape, "default=$server_rootdir", "invalid_choice="); if ($server_rootdir eq "none") { return(); } else { $server_rootdir = realpath($server_rootdir); my @located_servers = locate_server($server_rootdir); my @pServerHashes; foreach my $located_server (@located_servers) { my $pServerHash = { webserver_conf => $located_server, webserver_type => "netscape" }; if (cache_server($pServerHash)) { push @pServerHashes,$pServerHash; } } return(@pServerHashes); } } #------------------------------------------------------------------------------ # This method merely attempts to take the webserver information given to it # and tries to configure that webserver to work with a generated Sun Chili!Soft # ASP server. The server is generated on the fly. #------------------------------------------------------------------------------ sub configure { my $custom_install = boolean_value($pParameters->{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) { # Even if we support versions, we shall still # appreciate the generic modules. if ($CONST_UseNetscapeVersions) { # lets be more generic towards this. if ($_ =~ /netscape_([0-9]\.[a-zA-Z0-9])/) { push @supported_versions,$1; } } else { if ($_ =~ /netscape/) { push @supported_versions,$_; } } } 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); } # This routine is responsible for doing the actual configuration # changes for netscape 4. sub configure_casp2_NS4x { (@_ == 1) || die "Invalid number of arguments."; my ($pServerStats) = (@_) ; ## validate the parameters. if (! -f "$pServerStats->{webserver_obj_conf}" || ! -f "$pServerStats->{webserver_mime_types}" ) { error("ChiliAsp Installer cannot find some of your Web server configuration files", "Please verify your web server installation and try again ."); return (undef); } ########## This is the auxillary obj configuration. ## Update the obj.conf file to refer to the appropriate locations. copy($pServerStats->{webserver_obj_conf},"$pServerStats->{webserver_obj_conf}.pre-chiliasp"); my $dupname = "$pServerStats->{webserver_obj_conf}.chiliasp-install"; copy($pServerStats->{webserver_obj_conf},$dupname); #conf is the main configuration file, which contains the #server informations of this server. unless ((open(IN,"<$dupname")) && (open(OUT,">$pServerStats->{webserver_obj_conf}"))) { # Back out any changes. close(IN); close(OUT); copy("$pServerStats->{webserver_obj_conf}.pre-chiliasp",$pServerStats->{webserver_obj_conf}); unlink($dupname); error("Unable to open $pServerStats->{webserver_obj_conf} for modification.", "Skipping the server Configuration"); # Run cleanup code. return(undef); } my $inits = 0; my $service = 0; my $casptrans_written = 0; while () { s/\r//; if ((! $inits) && (/^Init/i)) { if ($CONST_UseNetscapeVersions) { my $major = $pServerStats->{webserver_major}; my $minor = $pServerStats->{webserver_minor}; print OUT qq!Init fn="load-modules" funcs="caspreq,caspinit,casptrans" shlib="$pGlobals->{module_dir}/netscape_$major.$CONST_NetscapeGenericMinorVersion/nes_casp2.$pGlobals->{lib_ext}"\nInit fn="caspinit" casplib="$pServerStats->{engine_dir}"\n!; } else { print OUT qq!Init fn="load-modules" funcs="caspreq,caspinit,casptrans" shlib="$pGlobals->{module_dir}/netscape/nes_casp2.$pGlobals->{lib_ext}"\nInit fn="caspinit" casplib="$pServerStats->{engine_dir}"\n!; } $inits = 1; } if (//i .. /<\/Object>/i) { if (/^NameTrans/i) { if (! $casptrans_written) { print OUT qq@NameTrans fn="casptrans"\n@; $casptrans_written = 1; } } if ((! $service) && (/^Service/i)) { print OUT qq!Service method=(GET|POST) type="chilisoft-internal/active-server-page" fn="caspreq" casplib="$pServerStats->{engine_dir}"\n!; $service = 1; } } print OUT if ((! /Init fn="load-modules" funcs="caspreq,caspinit,casptrans"|Init fn="caspinit"|Service method=\"?\(GET\|POST\).*fn="caspreq"|NameTrans fn="casptrans"|Init fn="load-modules" funcs="chiliasp,chiliaspinit"|Init fn="chiliaspinit"|Service method=\"?\(GET\|POST\).*fn="chiliasp"/i)); } close OUT; close IN; #remove the temporary files. unlink($dupname); ########## This is the auxillary mime.types configuration. ### Now time to proceed with "mime.types" my $dupname1 = "$pServerStats->{webserver_mime_types}.chiliasp-install"; copy($pServerStats->{webserver_mime_types},"$pServerStats->{webserver_mime_types}.pre-chiliasp"); copy($pServerStats->{webserver_mime_types},$dupname1); unless ((open(IN,"<$dupname1")) && (open(OUT,">$pServerStats->{webserver_mime_types}"))) { # Back out any changes. close(IN); close(OUT); copy("$pServerStats->{webserver_mime_types}.pre-chiliasp",$pServerStats->{webserver_mime_types}); unlink($dupname1); error("Unable to modify $pServerStats->{webserver_mime_types} ."); # Run cleanup code. return(undef); } while () { s/\r//; if (!(/^\s*\#/) && (/exts=(asp|asa)(,|\s)/i)) { print OUT "## by Sun Chili!Soft ASP install: " . $_; } else { print OUT if (!m@type=chilisoft-internal/active-server-page@i); } } print OUT "type=chilisoft-internal/active-server-page\texts=asp,asa\n"; close IN; close OUT; #remove the temporary files. unlink($dupname1); #all went fine. return(1); } # This routine is responsible for doing the actual configuration # changes for netscape 6. sub configure_casp2_NS6x { (@_ == 1) || die "Invalid number of arguments."; my ($pServerStats) = (@_) ; ## validate the parameters. if (! -f "$pServerStats->{webserver_obj_conf}" || ! -f "$pServerStats->{webserver_magnus_conf}" || ! -f "$pServerStats->{webserver_mime_types}" ) { error("ChiliAsp Installer cannot find some of your Web server configuration files", "Please verify your web server installation and try again ."); return (undef); } # For Netscape 6.0, the module initialization part is supposed to be # located in the magnus.conf. # this way we can do the new configuration changes here. my $netscape_version = $pServerStats->{webserver_major}; ########## This is the main magnus.conf configuration. copy($pServerStats->{webserver_magnus_conf},"$pServerStats->{webserver_magnus_conf}.pre-chiliasp"); my $dupname; $dupname = "$pServerStats->{webserver_magnus_conf}.chiliasp-install"; copy($pServerStats->{webserver_magnus_conf},$dupname); #conf is the main configuration file, which contains the #server informations of this server. unless ((open(IN,"<$dupname")) && (open(OUT,">$pServerStats->{webserver_magnus_conf}"))) { # Back out any changes. close(IN); close(OUT); copy("$pServerStats->{webserver_magnus_conf}.pre-chiliasp",$pServerStats->{webserver_magnus_conf}); unlink($dupname); error("Unable to open $pServerStats->{webserver_magnus_conf} for modification.", "Skipping the server Configuration"); return(undef); } my $inits = 0; while () { s/\r//; if ((! $inits) && (/^Init/i)) { if ($CONST_UseNetscapeVersions) { my $major = $pServerStats->{webserver_major}; my $minor = $pServerStats->{webserver_minor}; print OUT qq!Init fn="load-modules" funcs="caspreq,caspinit,casptrans" shlib="$pGlobals->{module_dir}/netscape_$major.$CONST_NetscapeGenericMinorVersion/nes_casp2.$pGlobals->{lib_ext}"\nInit fn="caspinit" casplib="$pServerStats->{engine_dir}"\n!; } else { print OUT qq!Init fn="load-modules" funcs="caspreq,caspinit,casptrans" shlib="$pGlobals->{module_dir}/netscape/nes_casp2.$pGlobals->{lib_ext}"\nInit fn="caspinit" casplib="$pServerStats->{engine_dir}"\n!; } $inits = 1; } print OUT if ((! /Init fn="load-modules" funcs="caspreq,caspinit,casptrans"|Init fn="caspinit"|Init fn="load-modules" funcs="chiliasp,chiliaspinit"|Init fn="chiliaspinit"/i)); } close OUT; close IN; #remove the temporary files. unlink($dupname); ########## This is the auxillary obj configuration. copy($pServerStats->{webserver_obj_conf},"$pServerStats->{webserver_obj_conf}.pre-chiliasp"); $dupname = "$pServerStats->{webserver_obj_conf}.chiliasp-install"; copy($pServerStats->{webserver_obj_conf},"$dupname"); #conf is the main configuration file, which contains the #server informations of this server. unless ((open(IN,"<$dupname")) && (open(OUT,">$pServerStats->{webserver_obj_conf}"))) { # Back out any changes. close(IN); close(OUT); copy("$pServerStats->{webserver_obj_conf}.pre-chiliasp",$pServerStats->{webserver_obj_conf}); unlink($dupname); error("Unable to open $pServerStats->{webserver_obj_conf} for modification.", "Skipping the server Configuration"); return(undef); } my $service = 0; my $casptrans_written = 0; while () { s/\r//; if (//i .. /<\/Object>/i) { if (/^NameTrans/i) { if (! $casptrans_written) { print OUT qq@NameTrans fn="casptrans"\n@; $casptrans_written = 1; } } if ((! $service) && (/^Service/i)) { print OUT qq!Service method=(GET|POST) type="chilisoft-internal/active-server-page" fn="caspreq" casplib="$pServerStats->{engine_dir}"\n!; $service = 1; } } print OUT if ((! /Service method=\"?\(GET\|POST\).*fn="caspreq"|NameTrans fn="casptrans"|Service method=\"?\(GET\|POST\).*fn="chiliasp"/i)); } close OUT; close IN; #remove the temporary files. unlink($dupname); ########## This is the auxillary mime.types configuration. my $dupname1 = "$pServerStats->{webserver_mime_types}.chiliasp-install"; copy($pServerStats->{webserver_mime_types},"$pServerStats->{webserver_mime_types}.pre-chiliasp"); copy($pServerStats->{webserver_mime_types},$dupname1); unless ((open(IN,"<$dupname1")) && (open(OUT,">$pServerStats->{webserver_mime_types}"))) { # Back out any changes. close(IN); close(OUT); copy("$pServerStats->{webserver_mime_types}.pre-chiliasp",$pServerStats->{webserver_mime_types}); unlink($dupname1); error("Unable to modify $pServerStats->{webserver_mime_types} ."); # Run cleanup code. return (undef); } while () { s/\r//; if (!(/^\s*\#/) && (/exts=(asp|asa)(,|\s)/i)) { print OUT "## by Sun Chili!Soft ASP install: " . $_; } else { print OUT if (!m@type=chilisoft-internal/active-server-page@i); } } print OUT "type=chilisoft-internal/active-server-page\texts=asp,asa\n"; close IN; close OUT; #remove the temporary files. unlink($dupname1); #all went fine. return(1); } # This is the main code for the configure routine. (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; (ref($pServerStats)) || die "Invalid argument passed."; my @supported_versions = detect_supported_versions; # Check version support. if ($CONST_UseNetscapeVersions) { my $ver = "$pServerStats->{webserver_major}"; $ver .= ".$CONST_NetscapeGenericMinorVersion" ; my $quoted_version = quotemeta($ver); if ($debug) { print "value of quoted version is $quoted_version\n"; print "version is $pServerStats->{webserver_version} \n"; print "major version is $pServerStats->{webserver_major} \n"; print "list of supported versions are @supported_versions \n"; note " "; } if (not grep { /$quoted_version/ } @supported_versions) { note("The specified version ($pServerStats->{webserver_version}) of Netscape is not", "currently supported. Sun Chili!Soft ASP will not be configured for", "this Netscape webserver"); report("Press Enter to continue ..."); ; return(undef); } } ########## 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 -d $pServerStats->{webserver_server_root}) { return(error("The specified Web server root '$pServerStats->{webserver_server_root}' does not exist.")); } # # Although magnus.conf points to the same file as webserver_conf,it doesnt hurt to treat this one # as a separate entry. # if (not -f $pServerStats->{webserver_conf}) { return(error("The specified Web server configuration file '$pServerStats->{webserver_conf}'", "does not exist.")); } if (not -f $pServerStats->{webserver_magnus_conf}) { return(error("The specified Web server configuration file '$pServerStats->{webserver_magnus_conf}'", "does not exist.")); } if (not -f $pServerStats->{webserver_obj_conf}) { return(error("The specified Web server Object configuration file '$pServerStats->{webserver_obj_conf}", "does not exist.")); } if (not -f $pServerStats->{webserver_mime_types}) { return(error("The specified Web server configuration file '$pServerStats->{webserver_mime_types}'", "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} !~ /netscape/i) { return(error("Attempting to configure a '$pServerStats->{webserver_type}' server with the", "Netscape module.")); } # Now that the configuration appears correct, we should recache the server # with the same information cache_server($pServerStats); ########## If the user wants auto startup of netscape and it's supported ... my $start_netscape = 0; my $supported_autostart = (exists $pServerStats->{webserver_start_script} && exists $pServerStats->{webserver_stop_script}); if ($supported_autostart) { $start_netscape = 1; if (exists $pParameters->{webserver_restart}) { $start_netscape = boolean_value($pParameters->{webserver_restart}); } } ### FIXME: We probably need a more distribution specific section of code here. if (interactive) { if ($supported_autostart && $custom_install) { $start_netscape = INSTALL::query::boolean_default ("Would you like this Netscape / iPlanet server restarted", $start_netscape); } } if (interactive) { print STDERR ("Configuring the $pServerStats->{webserver_name} Web server ... "); } my $pid = fork; if ($pid) { ##########========== Parent my $netscape_version = $pServerStats->{webserver_major} ; my $return_status = undef; if ($netscape_version > 4) { $return_status = configure_casp2_NS6x($pServerStats); } else { $return_status = configure_casp2_NS4x($pServerStats); } # configuration blown up, get out from here. if (! $return_status) { return(exit_parent($pid)); } my $restarted = 0; if ($start_netscape) { $restarted = restart_netscape($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 { # This routine is responsible for removing the configuration # changes for netscape 4. sub uninstall_casp2_NS4x { (@_ == 1) || die "Invalid number of arguments."; my ($pServerStats) = (@_) ; my $retVal = 1; ########## This is the auxillary obj configuration. if (-f $pServerStats->{webserver_obj_conf}) { unlink("$pServerStats->{webserver_obj_conf}.post-chiliasp"); copy($pServerStats->{webserver_obj_conf},"$pServerStats->{webserver_obj_conf}.post-chiliasp"); unless (open(IN,"<$pServerStats->{webserver_obj_conf}.post-chiliasp") && open(OUT,">$pServerStats->{webserver_obj_conf}")) { error("Unable to open $pServerStats->{webserver_obj_conf} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the obj.conf file. while () { s/\r//; print OUT if (!(/Init fn="load-modules" funcs="caspreq,caspinit,casptrans"|Init fn="caspinit"|Service method=\"?\(GET\|POST\).*fn="caspreq"|NameTrans fn="casptrans"|Init fn="load-modules" funcs="chiliasp,chiliaspinit"|Init fn="chiliaspinit"|Service method=\"?\(GET\|POST\).*fn="chiliasp"/i)); } close OUT; close IN; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_obj_conf}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_obj_conf} file.", "The Web server may have previously been removed."); $retVal = 2; } ########## This is the auxillary mime.types configuration. if (-f $pServerStats->{webserver_mime_types}) { unlink("$pServerStats->{webserver_mime_types}.post-chiliasp"); copy($pServerStats->{webserver_mime_types},"$pServerStats->{webserver_mime_types}.post-chiliasp"); unless (open(IN,"<$pServerStats->{webserver_mime_types}.post-chiliasp") && open(OUT,">$pServerStats->{webserver_mime_types}")) { error("Unable to open $pServerStats->{webserver_mime_types} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the mime.types file. while () { s/\r//; if (/^\s*\#\# by Sun Chili!Soft ASP install:\s*(.*)/) { print OUT "$1\n"; } else { print OUT if (!(m@type=chilisoft-internal/active-server-page@i)); } } close OUT; close IN; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_mime_types}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_mime_types} file.", "The Web server may have previously been removed."); $retVal = 2; } #all went fine. return($retVal); } # This routine is responsible for removing the configuration # changes for netscape 6x. sub uninstall_casp2_NS6x { (@_ == 1) || die "Invalid number of arguments."; my ($pServerStats) = (@_) ; my $retVal = 1; ########## This is the main magnus.conf configuration. if (-f $pServerStats->{webserver_magnus_conf}) { unlink("$pServerStats->{webserver_magnus_conf}.post-chiliasp"); copy($pServerStats->{webserver_magnus_conf},"$pServerStats->{webserver_magnus_conf}.post-chiliasp"); unless (open(IN,"<$pServerStats->{webserver_magnus_conf}.post-chiliasp") && open(OUT,">$pServerStats->{webserver_magnus_conf}")) { error("Unable to open $pServerStats->{webserver_magnus_conf} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the magnus.conf file. while () { s/\r//; print OUT if (!(/Init fn="load-modules" funcs="caspreq,caspinit,casptrans"|Init fn="caspinit"|Init fn="load-modules" funcs="chiliasp,chiliaspinit"|Init fn="chiliaspinit"/i)); } close OUT; close IN; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_magnus_conf}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_magnus_conf} file.", "The Web server may have previously been removed."); $retVal = 2; } ########## This is the auxillary obj configuration. if (-f $pServerStats->{webserver_obj_conf}) { unlink("$pServerStats->{webserver_obj_conf}.post-chiliasp"); copy($pServerStats->{webserver_obj_conf},"$pServerStats->{webserver_obj_conf}.post-chiliasp"); unless (open(IN,"<$pServerStats->{webserver_obj_conf}.post-chiliasp") && open(OUT,">$pServerStats->{webserver_obj_conf}")) { error("Unable to open $pServerStats->{webserver_obj_conf} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the obj.conf file. while () { s/\r//; print OUT if (!(/Service method=\"?\(GET\|POST\).*fn="caspreq"|NameTrans fn="casptrans"|Service method=\"?\(GET\|POST\).*fn="chiliasp"/i)); } close OUT; close IN; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_obj_conf}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_obj_conf} file.", "The Web server may have previously been removed."); $retVal = 2; } ########## This is the auxillary mime.types configuration. if (-f $pServerStats->{webserver_mime_types}) { unlink("$pServerStats->{webserver_mime_types}.post-chiliasp"); copy($pServerStats->{webserver_mime_types},"$pServerStats->{webserver_mime_types}.post-chiliasp"); unless (open(IN,"<$pServerStats->{webserver_mime_types}.post-chiliasp") && open(OUT,">$pServerStats->{webserver_mime_types}")) { error("Unable to open $pServerStats->{webserver_mime_types} for modification."); $retVal = 2; } else { ########## Strip any Sun Chili!Soft ASP line from the mime.types file. while () { s/\r//; if (/^\s*\#\# by Sun Chili!Soft ASP install:\s*(.*)/) { print OUT "$1\n"; } else { print OUT if (!(m@type=chilisoft-internal/active-server-page@i)); } } close OUT; close IN; } } else { error_log("Unable to access the webserver's $pServerStats->{webserver_mime_types}", "file. This may be a result of the Web server having been removed."); note_display("Unable to properly clean up the $pServerStats->{webserver_mime_types} file.", "The Web server may have previously been removed."); $retVal = 2; } #all went fine. return($retVal); } # This is the main code for the uninstall routine. (@_ == 1) || die "Invalid number of arguments."; my $pServerStats = shift @_; (ref($pServerStats)) || die "Invalid argument passed."; my $netscape_version = $pServerStats->{webserver_major} ; my $return_status = undef; if ($netscape_version > 4) { $return_status = uninstall_casp2_NS6x($pServerStats); } else { $return_status = uninstall_casp2_NS4x($pServerStats); } # configuration blown up, get out fas from here. if ($return_status == 1) { ########## Restart the webserver as appropriate. my $pidFile = "$pServerStats->{webserver_server_root}/logs/pid"; if (-f $pidFile) { if (exists $pServerStats->{webserver_start_script} && exists $pServerStats->{webserver_stop_script}) { my $answer = "y"; my $restart_netscape = 0; # initialize this to zero. if (exists $pParameters->{webserver_restart}) { $restart_netscape = boolean_value($pParameters->{webserver_restart}); } if (interactive && !$restart_netscape) { $answer = INSTALL::query::user ("Would you like this Netscape / iPlanet server restarted", "terminal_mark=?", "default=y", "n"); } my $restarted; if ($answer eq "y") { $restarted = restart_netscape($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 ..."); ; } } } } else { note("Unable to restart the $pServerStats->{webserver_name} Web server with configuration file:", " $pServerStats->{webserver_conf}"); } return($return_status); } #============================================================================== # Here is the series of helper routines related to processing the XML # information tags from the parsed XML tree. This parsed XML tree will be # now revamped so that we can make any meaning out of the parsed XML information. # Well, this is a sort of a roundabout way of doing things, but I believe # that this way we will be more generic with our XML parsing stuffs and then # we can collectively process the informations from the parsed XML tree. #============================================================================== #------------------------------------------------------------------------------ # This method should be able to parse & process the necessary XML tags # required by our cache server. # Input - requires the server.xml file to be passed in as input arguments. # Assumptions : 'server.xml should be in the same location as magnus.conf' #------------------------------------------------------------------------------ sub process_NS6XmlTags { # variables common to all the under subroutines. my $legacySocketId ; #------------------------------------------------------------------------------ # This method should be able to parse the given XML File. # Input - requires the server.xml file to be passed in as input arguments. # output - array reference of the vsclass_list. # Please refer to comments in process_vsclass routine for more detailed # description of the return type. # Assumptions : input 'server.xml'file should be in the same place as obj.conf #------------------------------------------------------------------------------ sub parse_NS6XmlTags { my ($server_xml) = (@_); # Validate the Parameters. ($#_ = 1) || die "Invalid number of arguments to parseNS6Xml_Tags"; if (! -f "$server_xml") { error("This routine needs to be called with a valid input file"); return (undef); } # obtain the config directory location from the server.xml file. my $webserver_config_dir = $server_xml; if ($webserver_config_dir =~ m@^/@) { $webserver_config_dir =~ s@^(.*)/server.xml$@$1@ ; } else { # TO DO:We need to construct a path name in this context also. return (error("Web server XML configuration file needs to be with absoulte path.")); } ###### Global hash table to store the parsed entry. my $pXmlRootNode ; unless (($pXmlRootNode = &INSTALL::chiliXML::build_XmlTree($server_xml))) { error("Unable to successfully build XML Tree from Configuration file $server_xml"); return (undef); } my $server = $pXmlRootNode ; # See if this server is built with the legacyls Socket concept.If it is there # then we will use this id to identify the realhost. if (exists $server->{'elementAttrs'}->{'legacyls'}) { $legacySocketId = $server->{'elementAttrs'}->{'legacyls'} ; $legacySocketId =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; } # # Now we will process the Main Child List from here. We will call appropriate # modes as input parameter. # my $pSocketInfoList ; my $pMimeInfo ; my $pVsClassInfoList ; # execute the following children in the sequential order. my $pChildNames = $server->{'child_names'} ; foreach my $name (sort @{$pChildNames}) { my $pElementList = INSTALL::chiliXML::queryAllElements_XmlNode($name,$server); unless (ref($pElementList)) { error ("Unable to retrieve the Child Nodes for Element:$name"); return (undef); } if ( "$name" eq "LS" ) { $pSocketInfoList = process_NS6XmlTagSocket($pElementList); if (! $pSocketInfoList) { return (undef); } } elsif ( "$name" eq "MIME" ) { $pMimeInfo = process_NS6XmlTagMime($pElementList); if (! $pMimeInfo) { return (undef); } } elsif ( "$name" eq "VSCLASS" ) { $pVsClassInfoList = process_NS6XmlTagVsclass ($pMimeInfo, $pSocketInfoList, $pElementList, $server_xml); if (! $pVsClassInfoList) { return (undef); } } } return ($pVsClassInfoList); } #------------------------------------------------------------------------------ # This helper routine parses the LS node from the XML tree. # Input - Array reference of the LS Node. # Output - Array reference (List of connection groups for a given obj.conf file) # Output data structure is represented as follows. # (group_list) = ( {GROUP_ATTR}, {GROUP_ATTR} ) # where, %GROUP_ATTR = (GROUP_ID => {SOCK_ATTR}) & # SOCK_ATTR = ( SOCK_ID, SOCK_IP, SOCK_PORT ) #------------------------------------------------------------------------------ sub process_NS6XmlTagSocket { ($#_ = 1) || die "processNS6Xml_TagSocket called with Insufficient parameters\n" ; # Array reference of the node 'LS'. my ($pSocketNodeList) = (@_) ; unless (ref($pSocketNodeList) eq "ARRAY") { error("Error occurred in routine processNS6Xml_TagSocket:The given input must be a reference to a ARRAY ", "This node must be a reference containing the list of node references for elementID LS"); return (undef); } # Array reference based on group id for output. my @group_list = (); # # First collect the attributes for this listen socket. # followed by their only child 'CONNECTION-GROUP' # foreach my $sock_element (@$pSocketNodeList) { my $sock_id ; my %sockattrs; foreach my $key (keys %{$sock_element->{'elementAttrs'}}) { my $sockValue = $sock_element->{'elementAttrs'}->{$key} ; $sockValue =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; # dump all data from the socket. $sockattrs{$key} = $sockValue ; $sock_id = $sockValue if ($key eq "id") ; # Presently we are identifying the realhost by the # legacy ls id. This might change in future. if ($sock_id eq $legacySocketId) { $sockattrs{"realhost"} = 1 ; } } my $pGroupElementAttrs = INSTALL::chiliXML::queryAllElements_XmlNode("CONNECTIONGROUP",$sock_element) ; unless (ref($pGroupElementAttrs)) { error ("Unable to retrieve the Child Nodes for Element:CONNECTIONGROUP"); return (undef); } foreach my $group_element (@{$pGroupElementAttrs}) { my $group_id ; foreach (keys %{$group_element->{'elementAttrs'}}) { my $groupValue = $group_element->{'elementAttrs'}->{$_} ; $groupValue =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; # dump all reqd data to socket table. ($_ eq 'id') ? ($sockattrs{'group_id'} = $group_id = $groupValue) : ($sockattrs{$_} = $groupValue) ; } my (%groupattr) = ($group_id => {%sockattrs}) ; push @group_list,{%groupattr}; } return (wantarray ? @group_list:[@group_list]); } } #------------------------------------------------------------------------------ # This helper routine parses the MIME node from the XML tree. # Input - Array reference of the MIME Node. # Output - Hash reference based on mime id. # for eg - %mimeInfo = ( mime_id => mime_type ) #------------------------------------------------------------------------------ sub process_NS6XmlTagMime { ($#_ == 0) || die "processNS6Xml_TagMime called with Insufficient parameters\n" ; # Input Array reference of the MIME Node. my ($pMimeNodeList) = (@_) ; unless (ref($pMimeNodeList) eq "ARRAY") { error("Error occurred in routine processNS6Xml_TagSocket:The given input must be a reference to a ARRAY ", "This node must be a reference containing the list of node references for elementID MIME"); return (undef); } # Output hash table containing mime id and mime types. my %mimeInfo ; foreach my $mime (@$pMimeNodeList) { my $mime_id ; my $mime_type ; my %attributes = %{$mime->{'elementAttrs'}}; foreach (keys %attributes) { $mime_id = $attributes{$_} if ($_ eq 'id') ; $mime_type = $attributes{$_} if ($_ eq 'file'); if ($mime_id && $mime_type) { $mime_id =~ s/^[\/"']+(\S+)[\/"']+/$1/; $mime_type =~ s/^[\/"']+(\S+)[\/"']+/$1/; $mimeInfo{$mime_id} = $mime_type ; } } } return (\%mimeInfo); } #------------------------------------------------------------------------------ # This helper routine parses the VSCLASS node from the XML tree. # Input - # - Array reference of the VSCLASS Node. # - Array reference of the group_list (contains the list of listen groups) # - hash reference of the mimeInfo ( contains the mime_id=>mime_type) # - Location of server XML configuration file. # Output - this is supposed to return a simplifed XML configuration. # - Array reference of vsclass_list - (contains virtual server class informations.) # Output data structure is represented as follows. # @vsclass_list = ( [vserver_list], [vserver_list] ) # where, @vserver_list = ( {vserver}, {vserver} ) # and %vserver = ( id => {%vserver_attributes} ) # and keys %vserver_attributes = ( objectfile, urlhosts ,port, mime, state ,vhost) #------------------------------------------------------------------------------ sub process_NS6XmlTagVsclass { ($#_ = 4) || die "processNS6Xml_TagVsclass called with Insufficient parameters\n" ; my ($pMimeInfo,$pSocketInfoList,$pVsClassNode,$server_xml) = (@_) ; my $webserver_config_dir; unless (ref($pMimeInfo) eq "HASH") { error("Error occurred in processNS6Xml_TagVsClass:MimeInfo must be a reference to a HASH"); return (undef); } unless (ref($pSocketInfoList) eq "ARRAY") { error("Error occurred in processNS6Xml_TagVsClass:SocketInfoList must be a reference to a ARRAY"); return (undef); } unless (ref($pVsClassNode) eq "ARRAY") { error("Error occurred in processNS6Xml_TagVsClass:The given input must be a reference to a ARRAY ", "This node must be a reference containing the list of node references for elementID VSCLASS"); return (undef); } unless (-f "$server_xml") { error("Error occurred in processNS6Xml_TagVsClass:Nees a valid XML Configuration file"); return (undef); } my %classInfo ; # Array of hashes representing all virtual servers classes in the XML file. my @vsclass_list = (); foreach my $class_element (@$pVsClassNode) { my $classid; my %classattrs; # Array of hashes representing all virtual servers within a class. my @vserver_list = (); foreach my $key (keys %{$class_element->{'elementAttrs'}}) { my $value = $class_element->{'elementAttrs'}->{$key} ; $value =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; # We need to save this , as this will be the primary key to # reach this server attributes. if ($key eq 'id') { $classid = $classattrs{'id'} = $value ; } elsif ($key eq 'objectfile') { my $conf = $class_element->{'elementAttrs'}->{$key} ; # Make relative path absolute. if ($conf !~ /^\//) { my $conf_dir = dirname($server_xml); my $obj_conf = $conf ; $obj_conf =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; $conf = "$conf_dir/$obj_conf" ; # fall back to standard if necessary. $conf = "$conf_dir/obj.conf" unless (-f "$conf"); } $classattrs{'objectfile'} = $conf ; } # we need this for future use. elsif ($key eq "rootobject") { $classattrs{$key} = $value ; } } # Presently we are interested in retrieving only the VS information only. # this constructs a hash table for a single virtual server based on id. my $pVServerList = INSTALL::chiliXML::queryAllElements_XmlNode("VS",$class_element); unless (ref($pVServerList )) { error ("Unable to retrieve the Child Nodes for Element:VS"); return (undef); } foreach my $vserver (@{$pVServerList}) { my $vs_id ; my $vs_port; # Hash representing the attributes for a single virtual server. my %vsattrs; foreach my $key (keys %{$vserver->{'elementAttrs'}}) { my $vsValue = $vserver->{'elementAttrs'}->{$key} ; $vsValue =~ s/^[\/"']+(\S+)[\/"']+/$1/ ; if ($key eq 'id') { # we need to save the primary key here for future reference. $vs_id = $vsattrs{'id'} = $vsValue ; } elsif ($key eq 'mime') { ($pMimeInfo->{$vsValue}) ? ($vsattrs{'mime'} = $pMimeInfo->{$vsValue}) : ($vsattrs{'mime'} = "mime.types") ; } elsif ($key eq 'connections') { my $group_id = $vsValue ; # initialize the real host boolean value here. my $port = undef ; my $realhost = undef ; foreach my $groupattr (@$pSocketInfoList) { foreach (keys %$groupattr) { if (($_ eq $group_id) && exists $groupattr->{$group_id}->{'realhost'}) { $realhost = $groupattr->{$group_id}->{'realhost'} ; } # we need more sophistication in choosing port number here. if ($_ eq $group_id) { $port = $groupattr->{$group_id}->{'port'} ; last ; } } last if ($port) ; } $vsattrs{'port'} = $port if ($port) ; $vsattrs{'realhost'} = $realhost if ($realhost) ; } elsif (($key eq 'state') || ($key eq 'urlhosts')) { $vsattrs{$key} = $vsValue ; } if (not exists $vsattrs{'objectfile'}) { $vsattrs{'objectfile'} = $classattrs{'objectfile'}; } if (not exists $vsattrs{'vhost'}) { $vsattrs{'vhost'} = $vsattrs{'urlhosts'} ; } } my (%vs) = ($vs_id => {%vsattrs}); push @vserver_list,\%vs; } push @vsclass_list,[@vserver_list]; } (wantarray) ? return (@vsclass_list) : return [@vsclass_list]; } #------------------------------------------------------------------------------ # This helper routine is responsible for filling the NS6ServerInfo data structure. # This routine will operate upon the vsclass_list data structure returned by # process_vsclass routine. Please refer to process_vsclass list routine for # more detailed description on the storage structure of vsclass_list. # Input - vsclass_list ( Array reference of all classes & servers under # the server.xml file. # Output - responsible for filling up server6Info structure. # Description of server6Info is described below :- # key is 'Netscape-Object-Configuration-FileName (eg obj.conf) # to keep the key unique, we need to store the absolute file name here. # and value is the REFERENCE TO A ARRAY of 'virutal Server' Informations. # for eg :- # pNS6ServerInfo->{"/usr/iplanet/servers/https-s1/config/obj.conf"} => A1(@Ref) # A1 can be further decomposed as # A1 = [ [ [VHOST_SERVERS ] ] and VHOST_SERVERS will have the VHOST_ATTS as keys # where, VHOST_ATTRS = [ PORT, MIME_TYPE, URLNAMES ] #------------------------------------------------------------------------------ sub buildCache_NS6ServerInfo { my ($pVsClassList) = (@_); ($#_ = 1) || die "buildCache_NS6ServerInfo called with Insufficient parameters \n"; unless (ref($pVsClassList) eq "ARRAY") { error("Input must be a reference to a ARRAY ", "This node must be a reference containing the list of node references for elementID VSCLASS"); return (undef); } my $return_value; my @objlist = (); my @vserver_list = (); if ( exists $pNS6ServerInfo->{'objectfile_list'} ) { push @objlist, @{$pNS6ServerInfo->{'objectfile_list'}} ; } if ( exists $pNS6ServerInfo->{'vserver_list'} ) { push @vserver_list, @{$pNS6ServerInfo->{'vserver_list'}} ; } foreach my $pVsServerList (@{$pVsClassList}) { foreach my $pVsServer (@{$pVsServerList}) { my $vhost_conf; foreach my $key (keys %{$pVsServer}) { my %serverAttrs = %{$pVsServer->{$key}} ; if (exists $pVsServer->{$key}->{'objectfile'}) { $vhost_conf = $pVsServer->{$key}->{'objectfile'}; if (not grep { m@$vhost_conf@ } @objlist) { push @objlist,$pVsServer->{$key}->{'objectfile'}; } } # # update the virtual servers for this conf file. # if this is a new virtual server for this conf file. # add this new virtual server for this conf file. # if (exists $pNS6ServerInfo->{$vhost_conf}) { my $vhost_list = $pNS6ServerInfo->{$vhost_conf}; push @$vhost_list,$pVsServer->{$key} ; $pNS6ServerInfo->{$vhost_conf} = $vhost_list ; } else { my @vhost_list; push @vhost_list, $pVsServer->{$key} ; $pNS6ServerInfo->{$vhost_conf} = [@vhost_list]; } } push @vserver_list,$pVsServer ; } } $pNS6ServerInfo->{'objectfile_list'} = [@objlist]; $pNS6ServerInfo->{'vserver_list'} = [@vserver_list]; return (1); } #------------------------------------------------------------------------------ # Here is the start of the routine - #------------------------------------------------------------------------------ # detect if the server.xml file is a complete file and if the file has any # relative file location return an error, ($#_ = 1) || die "processNS6XmlTags called with Insufficient parameters\n" ; my ($server_xml) = ( @_ ) ; if (($server_xml !~ m@^/@) || (! -f $server_xml)) { error ( "XML Configuration file name should be a valid absolute file name."); return (undef); } if (not $pNS6ServerInfo->{"$server_xml"}) { my $classInfoPtr = parse_NS6XmlTags($server_xml); if (! $classInfoPtr ) { return (undef); } my $error_status = buildCache_NS6ServerInfo($classInfoPtr); if (! $error_status ) { return (undef); } } return (1); } #------------------------------------------------------------------------------ # This routine is responsible for retrieving the required server configurations # from the pNS6ServerInfo data structure. # this works on the global hash table and retrieves the informations based upon # the query key specified as input arguments. # input - mode ( type of command to work upon.) & file name of the obj.conf file. # valid modes are (objectfile_list,vserver_list,realhost) # output - server configuration information is returned based on the mode passed. #------------------------------------------------------------------------------ sub retrieve_NS6ServerInfo { # first parameter is a operator key based on which we will do the querying. my ($function,$objectfile) = (@_) ; # validate the parameters and input key. ($#_ = 2) || die "retrieve_NS6ServerInfo - called with Insufficient parameters\n" ; my @valid_params = ("vserver_list","objectfile_list" ,"realhost"); my $valid_pattern = join('|',@valid_params) ; if (! $function || (not (grep {$function} $valid_pattern))) { error("retrieve_NS6ServerInfo - A valid funciton mode is NOT specified here", "The valid modes are realhost,vhost_list,object_list"); return (undef) ; } unless (ref($pNS6ServerInfo) && keys %{$pNS6ServerInfo}) { error("retrieve_NS6ServerInfo - Unable to validate any valid XML Server Information "); return (undef) ; } if (($objectfile !~ m@^/@) || (! -f $objectfile)) { error ( "Netscape object configuration file should be a valid absolute file ."); return (undef); } if (exists $pNS6ServerInfo->{$function}) { my $pKeyValue = $pNS6ServerInfo->{$function}; return ((wantarray) ? @$pKeyValue : $pKeyValue); } else { my @list = (); # This represents some query keys which are NOT available at the root level, so start checking out # for the list of virtual servers. unless (exists $pNS6ServerInfo->{$objectfile}) { error("retrieve_NS6ServerInfo - Unable to retrieve the list of Virtual Servers from the XML Configuration file."); return (undef); } my @pVServerList = @{$pNS6ServerInfo->{$objectfile}}; foreach my $pVServer (@pVServerList) { if (exists $pVServer->{$function}) { push @list,$pVServer ; } } return (undef) unless (@list); return ((wantarray) ? @list : $list[0]); } return (undef); } 1;