1#*************************************************************************
2#
3# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4#
5# Copyright 2000, 2010 Oracle and/or its affiliates.
6#
7# OpenOffice.org - a multi-platform office productivity suite
8#
9# This file is part of OpenOffice.org.
10#
11# OpenOffice.org is free software: you can redistribute it and/or modify
12# it under the terms of the GNU Lesser General Public License version 3
13# only, as published by the Free Software Foundation.
14#
15# OpenOffice.org is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18# GNU Lesser General Public License version 3 for more details
19# (a copy is included in the LICENSE file that accompanied this code).
20#
21# You should have received a copy of the GNU Lesser General Public License
22# version 3 along with OpenOffice.org.  If not, see
23# <http://www.openoffice.org/license.html>
24# for a copy of the LGPLv3 License.
25#
26#*************************************************************************
27
28package installer::setupscript;
29
30use installer::existence;
31use installer::exiter;
32use installer::globals;
33use installer::logger;
34use installer::remover;
35use installer::scriptitems;
36use installer::ziplist;
37
38#######################################################
39# Set setup script name, if not defined as parameter
40#######################################################
41
42sub set_setupscript_name
43{
44	my ( $allsettingsarrayref, $includepatharrayref ) = @_;
45
46	my $scriptnameref = installer::ziplist::getinfofromziplist($allsettingsarrayref, "script");
47
48	my $scriptname = $$scriptnameref;
49
50	if ( $scriptname eq "" )	# not defined on command line and not in product list
51	{
52		installer::exiter::exit_program("ERROR: Setup script not defined on command line (-l) and not in product list!", "set_setupscript_name");
53	}
54
55	if ( $installer::globals::compiler =~ /wnt/ )
56	{
57		$scriptname .= ".inf";
58	}
59	else
60	{
61		$scriptname .= ".ins";
62	}
63
64	# and now the complete path for the setup script is needed
65	# The log file cannot be used, because this is the language independent section
66
67	$scriptnameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptname, $includepatharrayref, 1);
68
69	$installer::globals::setupscriptname = $$scriptnameref;
70
71	if ( $installer::globals::setupscriptname eq "" )
72	{
73		installer::exiter::exit_program("ERROR: Script $scriptname not found!", "set_setupscript_name");
74	}
75}
76
77#####################################################################
78# Reading script variables from installation object of script file
79#####################################################################
80
81sub get_all_scriptvariables_from_installation_object
82{
83	my ($scriptref) = @_;
84
85	my @installobjectvariables;
86
87	for ( my $i = 0; $i <= $#{$scriptref}; $i++ )
88	{
89		my $line = ${$scriptref}[$i];
90
91		if ( $line =~ /^\s*Installation\s+\w+\s*$/ )	# should be the first line
92		{
93			my $counter = $i+1;
94			my $installline = ${$scriptref}[$counter];
95
96			while (!($installline =~ /^\s*End\s*$/ ))
97			{
98				if ( $installline =~ /^\s*(\w+)\s+\=\s*(.*?)\s*\;\s*$/ )
99				{
100					my $key = $1;
101					my $value = $2;
102
103					# removing leading and ending " in $value
104
105					if ( $value =~ /^\s*\"(.*)\"\s*$/ )
106					{
107						$value = $1;
108					}
109
110					$key = "\%" . uc($key);  # $key is %PRODUCTNAME
111
112					my $input = $key . " " . $value . "\n";	  # $key can only be the first word
113
114					push(@installobjectvariables ,$input);
115				}
116
117				$counter++;
118				$installline = ${$scriptref}[$counter];
119			}
120		}
121
122		last;	# not interesting after installation object
123	}
124
125	return \@installobjectvariables;
126}
127
128######################################################################
129# Including LCPRODUCTNAME into the array
130######################################################################
131
132sub add_lowercase_productname_setupscriptvariable
133{
134	my ( $variablesref ) = @_;
135
136	for ( my $j = 0; $j <= $#{$variablesref}; $j++ )
137	{
138		my $variableline = ${$variablesref}[$j];
139
140		my ($key, $value);
141
142		if ( $variableline =~ /^\s*\%(\w+?)\s+(.*?)\s*$/ )
143		{
144			$key = $1;
145			$value = $2;
146
147			if ( $key eq "PRODUCTNAME" )
148			{
149				my $newline = "\%LCPRODUCTNAME " . lc($value) . "\n";
150				push(@{$variablesref} ,$newline);
151				my $original = $value;
152				$value =~ s/\s*//g;
153				$newline = "\%ONEWORDPRODUCTNAME " . $value . "\n";
154				push(@{$variablesref} ,$newline);
155				$newline = "\%LCONEWORDPRODUCTNAME " . lc($value) . "\n";
156				push(@{$variablesref} ,$newline);
157				$value = $original;
158				$value =~ s/\s*$//g;
159				$value =~ s/^\s*//g;
160				$value =~ s/ /\%20/g;
161				$newline = "\%MASKEDPRODUCTNAME " . $value . "\n";
162				push(@{$variablesref} ,$newline);
163				$value = $original;
164				$value =~ s/\s/\_/g;
165				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; }
166				$newline = "\%UNIXPRODUCTNAME " . lc($value) . "\n";
167				push(@{$variablesref} ,$newline);
168				$newline = "\%SYSTEMINTUNIXPACKAGENAME " . lc($value) . "\n";
169				push(@{$variablesref} ,$newline);
170				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; }
171				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $2 . $4; }
172				$newline = "\%UNIXPACKAGENAME " . lc($value) . "\n";
173				push(@{$variablesref} ,$newline);
174				$value = $original;
175				$value =~ s/\s/\_/g;
176				$value =~ s/\.//g;
177				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; }
178				$newline = "\%WITHOUTDOTUNIXPRODUCTNAME " . lc($value) . "\n";
179				push(@{$variablesref} ,$newline);
180				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $1 . $2 . $4; }
181				# if ( $value =~ /^\s*(.*?)\_(\w)(.*?)\_(\w)(.*)\s*$/ ) { $value = $2 . $4; }
182				$newline = "\%WITHOUTDOTUNIXPACKAGENAME " . lc($value) . "\n";
183				push(@{$variablesref} ,$newline);
184				$newline = "\%SOLARISBRANDPACKAGENAME " . lc($value) . "\n";
185				push(@{$variablesref} ,$newline);
186				$value = $original;
187			}
188			elsif  ( $key eq "PRODUCTEXTENSION" )
189			{
190				my $newline = "\%LCPRODUCTEXTENSION " . lc($value) . "\n";
191				push(@{$variablesref} ,$newline);
192			}
193			elsif  ( $key eq "PRODUCTVERSION" )
194			{
195				$value =~ s/\.//g;
196				my $newline = "\%WITHOUTDOTPRODUCTVERSION " . $value . "\n";
197				push(@{$variablesref} ,$newline);
198			}
199			elsif  ( $key eq "OOOBASEVERSION" )
200			{
201				$value =~ s/\.//g;
202				my $newline = "\%WITHOUTDOTOOOBASEVERSION " . $value . "\n";
203				push(@{$variablesref} ,$newline);
204			}
205
206		}
207	}
208}
209
210######################################################################
211# Resolving the new introduced lowercase script variables
212######################################################################
213
214sub resolve_lowercase_productname_setupscriptvariable
215{
216	my ( $variablesref ) = @_;
217
218	my %variables = ();
219
220	# First step: Collecting variables
221
222	for ( my $j = 0; $j <= $#{$variablesref}; $j++ )
223	{
224		my $variableline = ${$variablesref}[$j];
225
226		my ($key, $value);
227
228		if ( $variableline =~ /^\s*\%(\w+?)\s+(.*?)\s*$/ )
229		{
230			$key = $1;
231			$value = $2;
232			$variables{$key} = $value;
233		}
234	}
235
236	# Second step: Resolving variables
237
238	for ( my $j = 0; $j <= $#{$variablesref}; $j++ )
239	{
240		if ( ${$variablesref}[$j] =~ /\$\{(.*?)\}/ )
241		{
242			my $key = $1;
243			${$variablesref}[$j] =~ s/\$\{\Q$key\E\}/$variables{$key}/g;
244		}
245	}
246
247}
248
249######################################################################
250# Replacing all setup script variables inside the setup script file
251######################################################################
252
253sub replace_all_setupscriptvariables_in_script
254{
255	my ( $scriptref, $variablesref ) = @_;
256
257	installer::logger::include_header_into_globallogfile("Replacing variables in setup script (start)");
258
259	# make hash of variables to be substituted if they appear in the script
260	my %subs;
261	for ( my $j = 0; $j <= $#{$variablesref}; $j++ )
262	{
263		my $variableline = ${$variablesref}[$j];
264
265		if ( $variableline =~ /^\s*(\%\w+?)\s+(.*?)\s*$/ )
266		{
267			$subs{$1}= $2;
268		}
269	}
270
271	# This is far faster than running a regexp for each line
272	my $bigstring = '';
273	for my $line (@{$scriptref}) { $bigstring = $bigstring . $line; }
274
275	foreach my $key ( keys %subs )
276	{
277		# Attention: It must be possible to substitute "%PRODUCTNAMEn", "%PRODUCTNAME%PRODUCTVERSIONabc"
278		my $value = $subs{$key};
279		$bigstring =~ s/$key/$value/g;
280	}
281
282	my @newlines = split /\n/, $bigstring;
283	$scriptref = \@newlines;
284
285	# now check for any mis-named '%' variables that we have left
286	my $num = 0;
287	for my $check (@newlines)
288	{
289		$num++;
290		if ( $check =~ /^.*\%\w+.*$/ )
291		{
292			if (( $check =~ /%1/ ) || ( $check =~ /%2/ ) || ( $check =~ /%verify/ )) { next; }
293			my $infoline = "WARNING: mis-named or un-known '%' variable in setup script at line $num:\n$check\n";
294			push( @installer::globals::globallogfileinfo, $infoline);
295			# print STDERR "Warning: mis-named or un-known '%' variable at line $num:\n$check\n";
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