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