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/ ))
289            {
290                next;
291            }
292            $installer::logger::Global->printf(
293                "WARNING: mis-named or un-known '%s' variable in setup script at line %s:\n",
294                "%", $num);
295            $installer::logger::Global->printf("%s\n", $check);
296		}
297	}
298
299	installer::logger::include_header_into_globallogfile("Replacing variables in setup script (end)");
300
301	return $scriptref;
302}
303
304#######################################################################
305# Collecting all items of the type "searchitem" from the setup script
306#######################################################################
307
308sub get_all_items_from_script
309{
310	my ($scriptref, $searchitem) = @_;
311
312	my @allitemarray = ();
313
314	my ($itemkey, $itemvalue, $valuecounter);
315
316	for ( my $i = 0; $i <= $#{$scriptref}; $i++ )
317	{
318		my $line = ${$scriptref}[$i];
319
320		if ( $line =~ /^\s*\Q$searchitem\E\s+(\S+)\s*$/ )
321		{
322			my $gid = $1;
323			my $counter = $i + 1;
324
325			my %oneitemhash = ();
326			my $ismultilang = 0;
327
328			$oneitemhash{'gid'} = $gid;
329
330			while  (!( $line =~ /^\s*End\s*$/ ))
331			{
332				if ( $counter > $#{$scriptref} ) {
333					installer::exiter::exit_program("Invalid setup script file. End of file reached before 'End' line of '$searchitem' section.", "get_all_items_from_script");
334				}
335				$line = ${$scriptref}[$counter];
336				$counter++;
337
338				if ( $line =~ /^\s*(.+?)\s*\=\s*(.+?)\s*\;\s*$/ )	# only oneliner!
339				{
340					$itemkey = $1;
341					$itemvalue = $2;
342
343					installer::remover::remove_leading_and_ending_quotationmarks(\$itemvalue);
344					$itemvalue =~ s/\s*$//; # removing ending whitespaces. Could be introduced by empty variables.
345
346					$oneitemhash{$itemkey} = $itemvalue;
347
348					if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ )
349					{
350						$ismultilang = 1;
351					}
352				}
353				else
354				{
355					if ( $searchitem eq "Module" ) # more than one line, for instance files at modules!
356					{
357						if (( $line =~ /^\s*(.+?)\s*\=\s*\(/ ) && (!($line =~ /\)\;\s*$ / )))
358						{
359							if ( $line =~ /^\s*(.+?)\s*\=\s*(.+)/ )	# the first line
360							{
361								$itemkey = $1;
362								$itemvalue = $2;
363								$itemvalue =~ s/\s*$//;
364							}
365
366							# collecting the complete itemvalue
367
368							$valuecounter = $counter;
369							$line = ${$scriptref}[$valuecounter];
370							installer::remover::remove_leading_and_ending_whitespaces(\$line);
371							$itemvalue = $itemvalue . $line;
372
373							while (!( $line =~ /\)\;\s*$/ ))
374							{
375								$valuecounter++;
376								$line = ${$scriptref}[$valuecounter];
377								installer::remover::remove_leading_and_ending_whitespaces(\$line);
378								$itemvalue = $itemvalue . $line;
379							}
380
381							# removing ending ";"
382							$itemvalue =~ s/\;\s*$//;
383
384							$oneitemhash{$itemkey} = $itemvalue;
385
386							if ( $itemkey =~ /^\s*\S+\s+\(\S+\)\s*$/ )
387							{
388								$ismultilang = 1;
389							}
390						}
391					}
392				}
393			}
394
395			$oneitemhash{'ismultilingual'} = $ismultilang;
396
397			push(@allitemarray, \%oneitemhash);
398		}
399	}
400
401	return \@allitemarray;
402}
403
404######################################################################
405# Collecting all folder at folderitems, that are predefined values
406# For example: PREDEFINED_AUTOSTART
407######################################################################
408
409sub add_predefined_folder
410{
411	my ( $folderitemref, $folderref ) = @_;
412
413	for ( my $i = 0; $i <= $#{$folderitemref}; $i++ )
414	{
415		my $folderitem = ${$folderitemref}[$i];
416		my $folderid = $folderitem->{'FolderID'};
417
418		if ( $folderid =~ /PREDEFINED_/ )
419		{
420			if (! installer::existence::exists_in_array_of_hashes("gid", $folderid, $folderref))
421			{
422				my %folder = ();
423				$folder{'ismultilingual'} = "0";
424				$folder{'Name'} = "";
425				$folder{'gid'} = $folderid;
426
427				push(@{$folderref}, \%folder);
428			}
429		}
430	}
431}
432
433#####################################################################################
434# If folderitems are non-advertised, the component needs to have a registry key
435# below HKCU as key path. Therefore it is required, to mark the file belonging
436# to a non-advertised shortcut, that a special userreg_xxx registry key can be
437# created during packing process.
438#####################################################################################
439
440sub prepare_non_advertised_files
441{
442	my ( $folderitemref, $filesref ) = @_;
443
444	for ( my $i = 0; $i <= $#{$folderitemref}; $i++ )
445	{
446		my $folderitem = ${$folderitemref}[$i];
447		my $styles = "";
448		if ( $folderitem->{'Styles'} ) { $styles = $folderitem->{'Styles'}; }
449
450		if ( $styles =~ /\bNON_ADVERTISED\b/ )
451		{
452			my $fileid = $folderitem->{'FileID'};
453			if ( $folderitem->{'ComponentIDFile'} ) { $fileid = $folderitem->{'ComponentIDFile'}; }
454			my $onefile = installer::worker::find_file_by_id($filesref, $fileid);
455
456			# Attention: If $onefile with "FileID" is not found, this is not always an error.
457			# FileID can also contain an executable file, for example msiexec.exe.
458			if ( $onefile ne "" ) { $onefile->{'needs_user_registry_key'} = 1; }
459		}
460	}
461}
462
463#####################################################################################
464# Adding all variables defined in the installation object into the hash
465# of all variables from the zip list file.
466# This is needed if variables are defined in the installation object,
467# but not in the zip list file.
468# If there is a definition in the zip list file and in the installation
469# object, the installation object is more important
470#####################################################################################
471
472sub add_installationobject_to_variables
473{
474	my ($allvariables, $allscriptvariablesref) = @_;
475
476	for ( my $i = 0; $i <= $#{$allscriptvariablesref}; $i++ )
477	{
478		my $line = ${$allscriptvariablesref}[$i];
479
480		if ( $line =~ /^\s*\%(\w+)\s+(.*?)\s*$/ )
481		{
482			my $key = $1;
483			my $value = $2;
484
485			$allvariables->{$key} = $value;	# overwrite existing values from zip.lst
486		}
487	}
488}
489
490#####################################################################################
491# Adding all variables, that must be defined, but are not defined until now.
492# List of this varibles: @installer::globals::forced_properties
493#####################################################################################
494
495sub add_forced_properties
496{
497	my ($allvariables) = @_;
498
499	my $property;
500	foreach $property ( @installer::globals::forced_properties )
501	{
502		if ( ! exists($allvariables->{$property}) ) { $allvariables->{$property} = ""; }
503	}
504}
505
506#####################################################################################
507# Some properties are created automatically. It should be possible to
508# overwrite them, with PRESET properties. For example UNIXPRODUCTNAME
509# with PRESETUNIXPRODUCTNAME, if this is defined and the automatic process
510# does not deliver the desired results.
511#####################################################################################
512
513sub replace_preset_properties
514{
515	my ($allvariables) = @_;
516
517	# SOLARISBRANDPACKAGENAME
518	# needs to be replaced by
519	# PRESETSOLARISBRANDPACKAGENAME
520
521	my @presetproperties = ();
522	push(@presetproperties, "SOLARISBRANDPACKAGENAME");
523	push(@presetproperties, "SYSTEMINTUNIXPACKAGENAME");
524	# push(@presetproperties, "UNIXPACKAGENAME");
525	# push(@presetproperties, "WITHOUTDOTUNIXPACKAGENAME");
526	# push(@presetproperties, "UNIXPRODUCTNAME");
527	# push(@presetproperties, "WITHOUTDOTUNIXPRODUCTNAME");
528
529
530	foreach $property ( @presetproperties )
531	{
532		my $presetproperty = "PRESET" . $property;
533		if (( exists($allvariables->{$presetproperty}) ) && ( $allvariables->{$presetproperty} ne "" ))
534		{
535			$allvariables->{$property} = $allvariables->{$presetproperty};
536		}
537	}
538}
539
5401;
541