xref: /trunk/main/solenv/bin/modules/installer/setupscript.pm (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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