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