1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21 22 23 24package installer::setupscript; 25 26use installer::existence; 27use installer::exiter; 28use installer::globals; 29use installer::logger; 30use installer::remover; 31use installer::scriptitems; 32use installer::ziplist; 33 34use strict; 35 36####################################################### 37# Set setup script name, if not defined as parameter 38####################################################### 39 40sub set_setupscript_name 41{ 42 my ( $allsettingsarrayref, $includepatharrayref ) = @_; 43 44 my $scriptnameref = installer::ziplist::getinfofromziplist($allsettingsarrayref, "script"); 45 46 my $scriptname = $$scriptnameref; 47 48 if ( $scriptname eq "" ) # not defined on command line and not in product list 49 { 50 installer::exiter::exit_program("ERROR: Setup script not defined on command line (-l) and not in product list!", "set_setupscript_name"); 51 } 52 53 if ( $installer::globals::compiler =~ /wnt/ ) 54 { 55 $scriptname .= ".inf"; 56 } 57 else 58 { 59 $scriptname .= ".ins"; 60 } 61 62 # and now the complete path for the setup script is needed 63 # The log file cannot be used, because this is the language independent section 64 65 $scriptnameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptname, $includepatharrayref, 1); 66 67 $installer::globals::setupscriptname = $$scriptnameref; 68 69 if ( $installer::globals::setupscriptname eq "" ) 70 { 71 installer::exiter::exit_program("ERROR: Script $scriptname not found!", "set_setupscript_name"); 72 } 73} 74 75##################################################################### 76# Reading script variables from installation object of script file 77##################################################################### 78 79sub get_all_scriptvariables_from_installation_object ($$) 80{ 81 my ($scriptref, $script_filename) = @_; 82 83 my $installobjectvariables = {}; 84 85 my $firstline = $scriptref->[0]; 86 if ($firstline !~ /^\s*Installation\s+\w+\s*$/) 87 { 88 installer::logger::PrintError("did not find 'Installation' keyword in first line of %s\n", 89 $script_filename); 90 } 91 foreach my $line (@$scriptref) 92 { 93 next if $line =~ /^\s*Installation\s+\w+\s*$/; # Already processed. 94 last if $line =~ /^\s*End\s*$/; 95 96 if ($line =~ /^\s*(\w+)\s+\=\s*\"?(.*?)\"?\s*\;\s*$/ ) 97 { 98 my ($key, $value) = ($1, $2); 99 100 $installobjectvariables->{uc($key)} = $value; 101 } 102 103 } 104 105 return $installobjectvariables; 106} 107 108###################################################################### 109# Including LCPRODUCTNAME into the array 110###################################################################### 111 112sub add_lowercase_productname_setupscriptvariable ($) 113{ 114 my ( $variablesref ) = @_; 115 116 my %additional_variables = (); 117 118 while (my ($key, $value) = each %$variablesref) 119 { 120 if ($key eq "PRODUCTNAME") 121 { 122 $additional_variables{"LCPRODUCTNAME"} = lc($value); 123 my $original = $value; 124 $value =~ s/\s+//g; 125 $additional_variables{"ONEWORDPRODUCTNAME"} = $value; 126 $additional_variables{"LCONEWORDPRODUCTNAME"} = lc($value); 127 $value = $original; 128 $value =~ s/(^\s+|\s+$)//g; 129 $value =~ s/ /\%20/g; 130 $additional_variables{"MASKEDPRODUCTNAME"} = $value; 131 $value = $original; 132 $value =~ s/\s/\_/g; 133 $additional_variables{"UNIXPRODUCTNAME"} = lc($value); 134 $additional_variables{"SYSTEMINTUNIXPACKAGENAME"} = lc($value); 135 $additional_variables{"UNIXPACKAGENAME"} = lc($value); 136 $value = $original; 137 $value =~ s/\s/\_/g; 138 $value =~ s/\.//g; 139 $additional_variables{"WITHOUTDOTUNIXPRODUCTNAME"} = lc($value); 140 $additional_variables{"WITHOUTDOTUNIXPACKAGENAME"} = lc($value); 141 $additional_variables{"SOLARISBRANDPACKAGENAME"} = lc($value); 142 } 143 elsif ($key eq "PRODUCTEXTENSION") 144 { 145 $additional_variables{"LCPRODUCTEXTENSION"} = lc($value); 146 } 147 elsif ($key eq "PRODUCTVERSION") 148 { 149 $value =~ s/\.//g; 150 $additional_variables{"WITHOUTDOTPRODUCTVERSION"} = $value; 151 } 152 elsif ($key eq "OOOBASEVERSION") 153 { 154 $value =~ s/\.//g; 155 $additional_variables{"WITHOUTDOTOOOBASEVERSION"} = $value; 156 } 157 } 158 159 while (my ($key, $value) = each %additional_variables) 160 { 161 $variablesref->{$key} = $value; 162 } 163} 164 165###################################################################### 166# Resolving the new introduced lowercase script variables 167###################################################################### 168 169sub resolve_lowercase_productname_setupscriptvariable ($) 170{ 171 my ($variablesref) = @_; 172 173 while (my ($key,$value) = each %$variablesref) 174 { 175 if ($value =~ /\$\{(.*?)\}/) 176 { 177 my $varname = $1; 178 my $replacement = $variablesref->{$varname}; 179 my $new_value = $value; 180 $new_value =~ s/\$\{\Q$varname\E\}/$replacement/g; 181 $variablesref->{$key} = $new_value; 182 } 183 } 184} 185 186 187 188 189###################################################################### 190# Replacing all setup script variables inside the setup script file 191###################################################################### 192 193sub replace_all_setupscriptvariables_in_script ($$) 194{ 195 my ($script_lines, $variables) = @_; 196 197 installer::logger::include_header_into_globallogfile("Replacing variables in setup script (start)"); 198 199 # This is far faster than running a regexp for each line 200 my $bigstring = join("", @$script_lines); 201 202 while (my ($key,$value) = each %$variables) 203 { 204 # Attention: It must be possible to substitute "%PRODUCTNAMEn", "%PRODUCTNAME%PRODUCTVERSIONabc" 205 my $count = ($bigstring =~ s/%$key/$value/g); 206 if ($count > 0) 207 { 208 $installer::logger::Lang->printf("replaced %s %d times\n", $key, $count); 209 } 210 } 211 212 my @newlines = split /\n/, $bigstring; 213 214 # now check for any mis-named '%' variables that we have left 215 my $num = 0; 216 foreach my $line (@newlines) 217 { 218 $num++; 219 if ($line =~ /\%\w+/) 220 { 221 if (( $line =~ /%1/ ) || ( $line =~ /%2/ ) || ( $line =~ /%verify/ )) 222 { 223 next; 224 } 225 $installer::logger::Info->printf( 226 "WARNING: mis-named or un-known %%-variable in setup script at line %s:\n",$num); 227 $installer::logger::Info->printf("%s\n", $line); 228 } 229 } 230 231 installer::logger::include_header_into_globallogfile("Replacing variables in setup script (end)"); 232 233 return \@newlines; 234} 235 236####################################################################### 237# Collecting all items of the type "searchitem" from the setup script 238####################################################################### 239 240sub get_all_items_from_script 241{ 242 my ($scriptref, $searchitem) = @_; 243 244 my @allitemarray = (); 245 246 my ($itemkey, $itemvalue, $valuecounter); 247 248 for ( my $i = 0; $i <= $#{$scriptref}; $i++ ) 249 { 250 my $line = ${$scriptref}[$i]; 251 252 if ( $line =~ /^\s*\Q$searchitem\E\s+(\S+)\s*$/ ) 253 { 254 my $gid = $1; 255 my $counter = $i + 1; 256 257 my %oneitemhash = (); 258 my $ismultilang = 0; 259 260 $oneitemhash{'gid'} = $gid; 261 262 while (!( $line =~ /^\s*End\s*$/ )) 263 { 264 if ( $counter > $#{$scriptref} ) { 265 installer::exiter::exit_program("Invalid setup script file. End of file reached before 'End' line of '$searchitem' section.", "get_all_items_from_script"); 266 } 267 $line = ${$scriptref}[$counter]; 268 $counter++; 269 270 if ( $line =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ ) # only oneliner! 271 { 272 $itemkey = $1; 273 $itemvalue = $2; 274 275 installer::remover::remove_leading_and_ending_quotationmarks(\$itemvalue); 276 $itemvalue =~ s/\s*$//; # removing ending whitespaces. Could be introduced by empty variables. 277 278 $oneitemhash{$itemkey} = $itemvalue; 279 280 if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ ) 281 { 282 $ismultilang = 1; 283 } 284 } 285 else 286 { 287 if ( $searchitem eq "Module" ) # more than one line, for instance files at modules! 288 { 289 if (( $line =~ /^\s*(.+?)\s*\=\s*\(/ ) && (!($line =~ /\)\;\s*$ / ))) 290 { 291 if ( $line =~ /^\s*(.+?)\s*\=\s*(.+)/ ) # the first line 292 { 293 $itemkey = $1; 294 $itemvalue = $2; 295 $itemvalue =~ s/\s*$//; 296 } 297 298 # collecting the complete itemvalue 299 300 $valuecounter = $counter; 301 $line = ${$scriptref}[$valuecounter]; 302 installer::remover::remove_leading_and_ending_whitespaces(\$line); 303 $itemvalue = $itemvalue . $line; 304 305 while (!( $line =~ /\)\;\s*$/ )) 306 { 307 $valuecounter++; 308 $line = ${$scriptref}[$valuecounter]; 309 installer::remover::remove_leading_and_ending_whitespaces(\$line); 310 $itemvalue = $itemvalue . $line; 311 } 312 313 # removing ending ";" 314 $itemvalue =~ s/\;\s*$//; 315 316 $oneitemhash{$itemkey} = $itemvalue; 317 318 if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ ) 319 { 320 $ismultilang = 1; 321 } 322 } 323 } 324 } 325 } 326 327 $oneitemhash{'ismultilingual'} = $ismultilang; 328 329 push(@allitemarray, \%oneitemhash); 330 } 331 } 332 333 return \@allitemarray; 334} 335 336###################################################################### 337# Collecting all folder at folderitems, that are predefined values 338# For example: PREDEFINED_AUTOSTART 339###################################################################### 340 341sub add_predefined_folder 342{ 343 my ( $folderitemref, $folderref ) = @_; 344 345 for ( my $i = 0; $i <= $#{$folderitemref}; $i++ ) 346 { 347 my $folderitem = ${$folderitemref}[$i]; 348 my $folderid = $folderitem->{'FolderID'}; 349 350 if ( $folderid =~ /PREDEFINED_/ ) 351 { 352 if (! installer::existence::exists_in_array_of_hashes("gid", $folderid, $folderref)) 353 { 354 my %folder = (); 355 $folder{'ismultilingual'} = "0"; 356 $folder{'Name'} = ""; 357 $folder{'gid'} = $folderid; 358 359 push(@{$folderref}, \%folder); 360 } 361 } 362 } 363} 364 365##################################################################################### 366# If folderitems are non-advertised, the component needs to have a registry key 367# below HKCU as key path. Therefore it is required, to mark the file belonging 368# to a non-advertised shortcut, that a special userreg_xxx registry key can be 369# created during packing process. 370##################################################################################### 371 372sub prepare_non_advertised_files 373{ 374 my ( $folderitemref, $filesref ) = @_; 375 376 for ( my $i = 0; $i <= $#{$folderitemref}; $i++ ) 377 { 378 my $folderitem = ${$folderitemref}[$i]; 379 my $styles = ""; 380 if ( $folderitem->{'Styles'} ) { $styles = $folderitem->{'Styles'}; } 381 382 if ( $styles =~ /\bNON_ADVERTISED\b/ ) 383 { 384 my $fileid = $folderitem->{'FileID'}; 385 if ( $folderitem->{'ComponentIDFile'} ) { $fileid = $folderitem->{'ComponentIDFile'}; } 386 my $onefile = installer::worker::find_file_by_id($filesref, $fileid); 387 388 # Attention: If $onefile with "FileID" is not found, this is not always an error. 389 # FileID can also contain an executable file, for example msiexec.exe. 390 if ( $onefile ne "" ) { $onefile->{'needs_user_registry_key'} = 1; } 391 } 392 } 393} 394 395##################################################################################### 396# Adding all variables defined in the installation object into the hash 397# of all variables from the zip list file. 398# This is needed if variables are defined in the installation object, 399# but not in the zip list file. 400# If there is a definition in the zip list file and in the installation 401# object, the installation object is more important 402##################################################################################### 403 404sub add_installationobject_to_variables ($$) 405{ 406 my ($variables, $script_variables) = @_; 407 408 while (my ($key, $value) = each %$script_variables) 409 { 410 $variables->{$key} = $value; # overwrite existing values from zip.lst 411 } 412} 413 414##################################################################################### 415# Adding all variables, that must be defined, but are not defined until now. 416# List of this varibles: @installer::globals::forced_properties 417##################################################################################### 418 419sub add_forced_properties 420{ 421 my ($allvariables) = @_; 422 423 my $property; 424 foreach $property ( @installer::globals::forced_properties ) 425 { 426 if ( ! exists($allvariables->{$property}) ) { $allvariables->{$property} = ""; } 427 } 428} 429 430##################################################################################### 431# Some properties are created automatically. It should be possible to 432# overwrite them, with PRESET properties. For example UNIXPRODUCTNAME 433# with PRESETUNIXPRODUCTNAME, if this is defined and the automatic process 434# does not deliver the desired results. 435##################################################################################### 436 437sub replace_preset_properties 438{ 439 my ($allvariables) = @_; 440 441 # SOLARISBRANDPACKAGENAME 442 # needs to be replaced by 443 # PRESETSOLARISBRANDPACKAGENAME 444 445 my @presetproperties = (); 446 push(@presetproperties, "SOLARISBRANDPACKAGENAME"); 447 push(@presetproperties, "SYSTEMINTUNIXPACKAGENAME"); 448 449 450 foreach my $property (@presetproperties) 451 { 452 my $presetproperty = "PRESET" . $property; 453 if (( exists($allvariables->{$presetproperty}) ) && ( $allvariables->{$presetproperty} ne "" )) 454 { 455 $allvariables->{$property} = $allvariables->{$presetproperty}; 456 } 457 } 458} 459 4601; 461