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 for ( my $i = 0; $i <= $#{$scriptref}; $i++ ) 86 { 87 my $line = ${$scriptref}[$i]; 88 89 if ( $line =~ /^\s*Installation\s+\w+\s*$/ ) # should be the first line 90 { 91 my $counter = $i+1; 92 my $installline = ${$scriptref}[$counter]; 93 94 while (!($installline =~ /^\s*End\s*$/ )) 95 { 96 if ( $installline =~ /^\s*(\w+)\s+\=\s*(.*?)\s*\;\s*$/ ) 97 { 98 my $key = $1; 99 my $value = $2; 100 101 # removing leading and ending " in $value 102 103 if ( $value =~ /^\s*\"(.*)\"\s*$/ ) 104 { 105 $value = $1; 106 } 107 108 $key = "\%" . uc($key); # $key is %PRODUCTNAME 109 110 my $input = $key . " " . $value . "\n"; # $key can only be the first word 111 112 push(@installobjectvariables ,$input); 113 } 114 115 $counter++; 116 $installline = ${$scriptref}[$counter]; 117 } 118 } 119 120 last; # not interesting after installation object 121 } 122 123 return \@installobjectvariables; 124} 125 126###################################################################### 127# Including LCPRODUCTNAME into the array 128###################################################################### 129 130sub add_lowercase_productname_setupscriptvariable 131{ 132 my ( $variablesref ) = @_; 133 134 for ( my $j = 0; $j <= $#{$variablesref}; $j++ ) 135 { 136 my $variableline = ${$variablesref}[$j]; 137 138 my ($key, $value); 139 140 if ( $variableline =~ /^\s*\%(\w+?)\s+(.*?)\s*$/ ) 141 { 142 $key = $1; 143 $value = $2; 144 145 if ( $key eq "PRODUCTNAME" ) 146 { 147 my $newline = "\%LCPRODUCTNAME " . lc($value) . "\n"; 148 push(@{$variablesref} ,$newline); 149 my $original = $value; 150 $value =~ s/\s*//g; 151 $newline = "\%ONEWORDPRODUCTNAME " . $value . "\n"; 152 push(@{$variablesref} ,$newline); 153 $newline = "\%LCONEWORDPRODUCTNAME " . lc($value) . "\n"; 154 push(@{$variablesref} ,$newline); 155 $value = $original; 156 $value =~ s/\s*$//g; 157 $value =~ s/^\s*//g; 158 $value =~ s/ /\%20/g; 159 $newline = "\%MASKEDPRODUCTNAME " . $value . "\n"; 160 push(@{$variablesref} ,$newline); 161 $value = $original; 162 $value =~ s/\s/\_/g; 163 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; } 164 $newline = "\%UNIXPRODUCTNAME " . lc($value) . "\n"; 165 push(@{$variablesref} ,$newline); 166 $newline = "\%SYSTEMINTUNIXPACKAGENAME " . lc($value) . "\n"; 167 push(@{$variablesref} ,$newline); 168 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; } 169 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $2 . $4; } 170 $newline = "\%UNIXPACKAGENAME " . lc($value) . "\n"; 171 push(@{$variablesref} ,$newline); 172 $value = $original; 173 $value =~ s/\s/\_/g; 174 $value =~ s/\.//g; 175 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; } 176 $newline = "\%WITHOUTDOTUNIXPRODUCTNAME " . lc($value) . "\n"; 177 push(@{$variablesref} ,$newline); 178 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; } 179 # if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $2 . $4; } 180 $newline = "\%WITHOUTDOTUNIXPACKAGENAME " . lc($value) . "\n"; 181 push(@{$variablesref} ,$newline); 182 $newline = "\%SOLARISBRANDPACKAGENAME " . lc($value) . "\n"; 183 push(@{$variablesref} ,$newline); 184 $value = $original; 185 } 186 elsif ( $key eq "PRODUCTEXTENSION" ) 187 { 188 my $newline = "\%LCPRODUCTEXTENSION " . lc($value) . "\n"; 189 push(@{$variablesref} ,$newline); 190 } 191 elsif ( $key eq "PRODUCTVERSION" ) 192 { 193 $value =~ s/\.//g; 194 my $newline = "\%WITHOUTDOTPRODUCTVERSION " . $value . "\n"; 195 push(@{$variablesref} ,$newline); 196 } 197 elsif ( $key eq "OOOBASEVERSION" ) 198 { 199 $value =~ s/\.//g; 200 my $newline = "\%WITHOUTDOTOOOBASEVERSION " . $value . "\n"; 201 push(@{$variablesref} ,$newline); 202 } 203 204 } 205 } 206} 207 208###################################################################### 209# Resolving the new introduced lowercase script variables 210###################################################################### 211 212sub resolve_lowercase_productname_setupscriptvariable 213{ 214 my ( $variablesref ) = @_; 215 216 my %variables = (); 217 218 # First step: Collecting variables 219 220 for ( my $j = 0; $j <= $#{$variablesref}; $j++ ) 221 { 222 my $variableline = ${$variablesref}[$j]; 223 224 my ($key, $value); 225 226 if ( $variableline =~ /^\s*\%(\w+?)\s+(.*?)\s*$/ ) 227 { 228 $key = $1; 229 $value = $2; 230 $variables{$key} = $value; 231 } 232 } 233 234 # Second step: Resolving variables 235 236 for ( my $j = 0; $j <= $#{$variablesref}; $j++ ) 237 { 238 if ( ${$variablesref}[$j] =~ /\$\{(.*?)\}/ ) 239 { 240 my $key = $1; 241 ${$variablesref}[$j] =~ s/\$\{\Q$key\E\}/$variables{$key}/g; 242 } 243 } 244 245} 246 247###################################################################### 248# Replacing all setup script variables inside the setup script file 249###################################################################### 250 251sub replace_all_setupscriptvariables_in_script 252{ 253 my ( $scriptref, $variablesref ) = @_; 254 255 installer::logger::include_header_into_globallogfile("Replacing variables in setup script (start)"); 256 257 # make hash of variables to be substituted if they appear in the script 258 my %subs; 259 for ( my $j = 0; $j <= $#{$variablesref}; $j++ ) 260 { 261 my $variableline = ${$variablesref}[$j]; 262 263 if ( $variableline =~ /^\s*(\%\w+?)\s+(.*?)\s*$/ ) 264 { 265 $subs{$1}= $2; 266 } 267 } 268 269 # This is far faster than running a regexp for each line 270 my $bigstring = ''; 271 for my $line (@{$scriptref}) { $bigstring = $bigstring . $line; } 272 273 foreach my $key ( keys %subs ) 274 { 275 # Attention: It must be possible to substitute "%PRODUCTNAMEn", "%PRODUCTNAME%PRODUCTVERSIONabc" 276 my $value = $subs{$key}; 277 $bigstring =~ s/$key/$value/g; 278 } 279 280 my @newlines = split /\n/, $bigstring; 281 $scriptref = \@newlines; 282 283 # now check for any mis-named '%' variables that we have left 284 my $num = 0; 285 for my $check (@newlines) 286 { 287 $num++; 288 if ( $check =~ /^.*\%\w+.*$/ ) 289 { 290 if (( $check =~ /%1/ ) || ( $check =~ /%2/ ) || ( $check =~ /%verify/ )) 291 { 292 next; 293 } 294 $installer::logger::Global->printf( 295 "WARNING: mis-named or un-known '%s' variable in setup script at line %s:\n", 296 "%", $num); 297 $installer::logger::Global->printf("%s\n", $check); 298 } 299 } 300 301 installer::logger::include_header_into_globallogfile("Replacing variables in setup script (end)"); 302 303 return $scriptref; 304} 305 306####################################################################### 307# Collecting all items of the type "searchitem" from the setup script 308####################################################################### 309 310sub get_all_items_from_script 311{ 312 my ($scriptref, $searchitem) = @_; 313 314 my @allitemarray = (); 315 316 my ($itemkey, $itemvalue, $valuecounter); 317 318 for ( my $i = 0; $i <= $#{$scriptref}; $i++ ) 319 { 320 my $line = ${$scriptref}[$i]; 321 322 if ( $line =~ /^\s*\Q$searchitem\E\s+(\S+)\s*$/ ) 323 { 324 my $gid = $1; 325 my $counter = $i + 1; 326 327 my %oneitemhash = (); 328 my $ismultilang = 0; 329 330 $oneitemhash{'gid'} = $gid; 331 332 while (!( $line =~ /^\s*End\s*$/ )) 333 { 334 if ( $counter > $#{$scriptref} ) { 335 installer::exiter::exit_program("Invalid setup script file. End of file reached before 'End' line of '$searchitem' section.", "get_all_items_from_script"); 336 } 337 $line = ${$scriptref}[$counter]; 338 $counter++; 339 340 if ( $line =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ ) # only oneliner! 341 { 342 $itemkey = $1; 343 $itemvalue = $2; 344 345 installer::remover::remove_leading_and_ending_quotationmarks(\$itemvalue); 346 $itemvalue =~ s/\s*$//; # removing ending whitespaces. Could be introduced by empty variables. 347 348 $oneitemhash{$itemkey} = $itemvalue; 349 350 if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ ) 351 { 352 $ismultilang = 1; 353 } 354 } 355 else 356 { 357 if ( $searchitem eq "Module" ) # more than one line, for instance files at modules! 358 { 359 if (( $line =~ /^\s*(.+?)\s*\=\s*\(/ ) && (!($line =~ /\)\;\s*$ / ))) 360 { 361 if ( $line =~ /^\s*(.+?)\s*\=\s*(.+)/ ) # the first line 362 { 363 $itemkey = $1; 364 $itemvalue = $2; 365 $itemvalue =~ s/\s*$//; 366 } 367 368 # collecting the complete itemvalue 369 370 $valuecounter = $counter; 371 $line = ${$scriptref}[$valuecounter]; 372 installer::remover::remove_leading_and_ending_whitespaces(\$line); 373 $itemvalue = $itemvalue . $line; 374 375 while (!( $line =~ /\)\;\s*$/ )) 376 { 377 $valuecounter++; 378 $line = ${$scriptref}[$valuecounter]; 379 installer::remover::remove_leading_and_ending_whitespaces(\$line); 380 $itemvalue = $itemvalue . $line; 381 } 382 383 # removing ending ";" 384 $itemvalue =~ s/\;\s*$//; 385 386 $oneitemhash{$itemkey} = $itemvalue; 387 388 if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ ) 389 { 390 $ismultilang = 1; 391 } 392 } 393 } 394 } 395 } 396 397 $oneitemhash{'ismultilingual'} = $ismultilang; 398 399 push(@allitemarray, \%oneitemhash); 400 } 401 } 402 403 return \@allitemarray; 404} 405 406###################################################################### 407# Collecting all folder at folderitems, that are predefined values 408# For example: PREDEFINED_AUTOSTART 409###################################################################### 410 411sub add_predefined_folder 412{ 413 my ( $folderitemref, $folderref ) = @_; 414 415 for ( my $i = 0; $i <= $#{$folderitemref}; $i++ ) 416 { 417 my $folderitem = ${$folderitemref}[$i]; 418 my $folderid = $folderitem->{'FolderID'}; 419 420 if ( $folderid =~ /PREDEFINED_/ ) 421 { 422 if (! installer::existence::exists_in_array_of_hashes("gid", $folderid, $folderref)) 423 { 424 my %folder = (); 425 $folder{'ismultilingual'} = "0"; 426 $folder{'Name'} = ""; 427 $folder{'gid'} = $folderid; 428 429 push(@{$folderref}, \%folder); 430 } 431 } 432 } 433} 434 435##################################################################################### 436# If folderitems are non-advertised, the component needs to have a registry key 437# below HKCU as key path. Therefore it is required, to mark the file belonging 438# to a non-advertised shortcut, that a special userreg_xxx registry key can be 439# created during packing process. 440##################################################################################### 441 442sub prepare_non_advertised_files 443{ 444 my ( $folderitemref, $filesref ) = @_; 445 446 for ( my $i = 0; $i <= $#{$folderitemref}; $i++ ) 447 { 448 my $folderitem = ${$folderitemref}[$i]; 449 my $styles = ""; 450 if ( $folderitem->{'Styles'} ) { $styles = $folderitem->{'Styles'}; } 451 452 if ( $styles =~ /\bNON_ADVERTISED\b/ ) 453 { 454 my $fileid = $folderitem->{'FileID'}; 455 if ( $folderitem->{'ComponentIDFile'} ) { $fileid = $folderitem->{'ComponentIDFile'}; } 456 my $onefile = installer::worker::find_file_by_id($filesref, $fileid); 457 458 # Attention: If $onefile with "FileID" is not found, this is not always an error. 459 # FileID can also contain an executable file, for example msiexec.exe. 460 if ( $onefile ne "" ) { $onefile->{'needs_user_registry_key'} = 1; } 461 } 462 } 463} 464 465##################################################################################### 466# Adding all variables defined in the installation object into the hash 467# of all variables from the zip list file. 468# This is needed if variables are defined in the installation object, 469# but not in the zip list file. 470# If there is a definition in the zip list file and in the installation 471# object, the installation object is more important 472##################################################################################### 473 474sub add_installationobject_to_variables 475{ 476 my ($allvariables, $allscriptvariablesref) = @_; 477 478 for ( my $i = 0; $i <= $#{$allscriptvariablesref}; $i++ ) 479 { 480 my $line = ${$allscriptvariablesref}[$i]; 481 482 if ( $line =~ /^\s*\%(\w+)\s+(.*?)\s*$/ ) 483 { 484 my $key = $1; 485 my $value = $2; 486 487 $allvariables->{$key} = $value; # overwrite existing values from zip.lst 488 } 489 } 490} 491 492##################################################################################### 493# Adding all variables, that must be defined, but are not defined until now. 494# List of this varibles: @installer::globals::forced_properties 495##################################################################################### 496 497sub add_forced_properties 498{ 499 my ($allvariables) = @_; 500 501 my $property; 502 foreach $property ( @installer::globals::forced_properties ) 503 { 504 if ( ! exists($allvariables->{$property}) ) { $allvariables->{$property} = ""; } 505 } 506} 507 508##################################################################################### 509# Some properties are created automatically. It should be possible to 510# overwrite them, with PRESET properties. For example UNIXPRODUCTNAME 511# with PRESETUNIXPRODUCTNAME, if this is defined and the automatic process 512# does not deliver the desired results. 513##################################################################################### 514 515sub replace_preset_properties 516{ 517 my ($allvariables) = @_; 518 519 # SOLARISBRANDPACKAGENAME 520 # needs to be replaced by 521 # PRESETSOLARISBRANDPACKAGENAME 522 523 my @presetproperties = (); 524 push(@presetproperties, "SOLARISBRANDPACKAGENAME"); 525 push(@presetproperties, "SYSTEMINTUNIXPACKAGENAME"); 526 527 528 foreach my $property (@presetproperties) 529 { 530 my $presetproperty = "PRESET" . $property; 531 if (( exists($allvariables->{$presetproperty}) ) && ( $allvariables->{$presetproperty} ne "" )) 532 { 533 $allvariables->{$property} = $allvariables->{$presetproperty}; 534 } 535 } 536} 537 5381; 539