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