cid#1606940 Check of thread-shared field evades lock acquisition
[LibreOffice.git] / solenv / bin / modules / installer / packagelist.pm
blobaef4f94015b430190db59b822a01116c59607254
2 # This file is part of the LibreOffice project.
4 # This Source Code Form is subject to the terms of the Mozilla Public
5 # License, v. 2.0. If a copy of the MPL was not distributed with this
6 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 # This file incorporates work covered by the following license notice:
10 # Licensed to the Apache Software Foundation (ASF) under one or more
11 # contributor license agreements. See the NOTICE file distributed
12 # with this work for additional information regarding copyright
13 # ownership. The ASF licenses this file to you under the Apache
14 # License, Version 2.0 (the "License"); you may not use this file
15 # except in compliance with the License. You may obtain a copy of
16 # the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 package installer::packagelist;
21 use strict;
22 use warnings;
24 use installer::converter;
25 use installer::exiter;
26 use installer::globals;
27 use installer::remover;
28 use installer::scriptitems;
30 ########################################
31 # Check existence of module
32 ########################################
34 sub check_module_existence
36 my ($onegid, $moduleslist) = @_;
38 my $foundgid = 0;
40 for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
42 my $gid = ${$moduleslist}[$i]->{'gid'};
44 if ( $gid eq $onegid )
46 $foundgid = 1;
47 last;
51 return $foundgid;
54 ###################################################
55 # Analyzing the gids, defined in the packagelist
56 ###################################################
58 sub analyze_list
60 my ($packagelist, $moduleslist) = @_;
62 my @allpackages = ();
64 my $moduleshash = get_module_hash($moduleslist);
66 for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
68 my $onepackage = ${$packagelist}[$i];
70 my $onegid = $onepackage->{'module'};
72 installer::remover::remove_leading_and_ending_whitespaces(\$onegid);
74 my $moduleexists = check_module_existence($onegid, $moduleslist);
76 if ( ! $moduleexists ) { next; }
78 my @allmodules = ();
80 push(@allmodules, $onegid);
82 get_children_with_hash($moduleshash, $onegid, \@allmodules);
84 $onepackage->{'allmodules'} = \@allmodules;
86 push(@allpackages, $onepackage);
89 return \@allpackages;
92 ###################################################
93 # Creating a hash, that contains the module gids
94 # as keys and the parentids as values
95 ###################################################
97 sub get_module_hash
99 my ($moduleslist) = @_;
101 my %modulehash = ();
103 for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
105 my $gid = ${$moduleslist}[$i]->{'gid'};
106 # Containing only modules with parent. Root modules can be ignored.
107 if ( ${$moduleslist}[$i]->{'ParentID'} ) { $modulehash{$gid} = ${$moduleslist}[$i]->{'ParentID'}; }
110 return \%modulehash;
113 ########################################################
114 # Recursively defined procedure to order
115 # modules and directories
116 ########################################################
118 sub get_children_with_hash
120 my ($modulehash, $parentgid, $newitemorder) = @_;
122 foreach my $gid ( keys %{$modulehash} )
124 my $parent = $modulehash->{$gid};
126 if ( $parent eq $parentgid )
128 push(@{$newitemorder}, $gid);
129 my $parent = $gid;
130 get_children_with_hash($modulehash, $parent, $newitemorder); # recursive!
135 ########################################################
136 # Recursively defined procedure to order
137 # modules and directories
138 ########################################################
140 sub get_children
142 my ($allitems, $startparent, $newitemorder) = @_;
144 for ( my $i = 0; $i <= $#{$allitems}; $i++ )
146 my $gid = ${$allitems}[$i]->{'gid'};
147 my $parent = "";
148 if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; }
150 if ( $parent eq $startparent )
152 push(@{$newitemorder}, $gid);
153 my $parent = $gid;
154 get_children($allitems, $parent, $newitemorder); # recursive!
159 #####################################################################
160 # All modules below a defined gid_Module_A are collected now for
161 # each modules defined in the packagelist. Now the modules have
162 # to be removed, that are part of more than one package.
163 #####################################################################
165 sub remove_multiple_modules_packages
167 my ($allpackagemodules) = @_;
169 # iterating over all packages
171 for ( my $i = 0; $i <= $#{$allpackagemodules}; $i++ )
173 my $onepackage = ${$allpackagemodules}[$i];
174 my $allmodules = $onepackage->{'allmodules'};
176 # Comparing each package, with all following packages. If a
177 # gid for the module is part of more than one package, it is
178 # removed if the number of modules in the package is greater
179 # in the current package than in the compare package.
181 # Taking all modules from package $i
183 my $packagecount = $#{$allmodules};
185 my @optimizedpackage = ();
187 # iterating over all modules of this package
189 for ( my $j = 0; $j <= $#{$allmodules}; $j++ )
191 my $onemodule = ${$allmodules}[$j]; # this is the module, that shall be removed or not
193 my $put_module_into_new_package = 1;
195 # iterating over all other packages
197 for ( my $k = 0; $k <= $#{$allpackagemodules}; $k++ )
199 if ( $k == $i ) { next; } # not comparing equal module
201 if (! $put_module_into_new_package) { next; } # do not compare, if already found
203 my $comparepackage = ${$allpackagemodules}[$k];
204 my $allcomparemodules = $comparepackage->{'allmodules'};
206 my $comparepackagecount = $#{$allcomparemodules};
208 # modules will only be removed from packages, that have more modules
209 # than the compare package
211 if ( $packagecount < $comparepackagecount ) { next; } # nothing to do, take next package
213 # iterating over all modules of this package
215 for ( my $m = 0; $m <= $#{$allcomparemodules}; $m++ )
217 my $onecomparemodule = ${$allcomparemodules}[$m];
219 if ( $onemodule eq $onecomparemodule ) # this $onemodule has to be removed
221 $put_module_into_new_package = 0;
226 if ( $put_module_into_new_package )
228 push(@optimizedpackage, $onemodule)
232 $onepackage->{'allmodules'} = \@optimizedpackage;
236 #####################################################################
237 # Analyzing all files if they belong to a special package.
238 # A package is described by a list of modules.
239 #####################################################################
241 sub find_files_for_package
243 my ($filelist, $onepackage) = @_;
245 my @newfilelist;
246 my $lastmodules = '';
247 my $lastincludefile = 0;
249 my %packagemodules = map {$_ => 1} @{$onepackage->{'allmodules'}};
251 for my $onefile (@$filelist)
253 my $modulesstring = $onefile->{'modules'}; # comma separated modules list
255 # check if the modules string is the same as in the last file
256 if ($modulesstring eq $lastmodules)
258 push(@newfilelist, $onefile) if $lastincludefile;
259 next;
262 my $moduleslist = installer::converter::convert_stringlist_into_array(\$modulesstring, ",");
264 my $includefile = 0;
266 # iterating over all modules of this file
267 for my $filemodule (@$moduleslist) {
268 installer::remover::remove_leading_and_ending_whitespaces(\$filemodule);
269 if ($packagemodules{$filemodule}) {
270 $includefile = 1;
271 last;
275 push(@newfilelist, $onefile) if $includefile;
277 # cache last result for this modules list
278 $lastmodules = $modulesstring;
279 $lastincludefile = $includefile;
282 return \@newfilelist;
285 #####################################################################
286 # Analyzing all links if they belong to a special package.
287 # A package is described by a list of modules.
288 # A link is inserted into the package, if the corresponding
289 # file is also inserted.
290 #####################################################################
292 sub find_links_for_package
294 my ($linklist, $filelist) = @_;
296 # First looking for all links with a FileID.
297 # Then looking for all links with a ShortcutID.
299 my @newlinklist = ();
301 for ( my $i = 0; $i <= $#{$linklist}; $i++ )
303 my $includelink = 0;
305 my $onelink = ${$linklist}[$i];
307 my $fileid = "";
308 if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; }
310 if ( $fileid eq "" ) { next; } # A link with a ShortcutID
312 for ( my $j = 0; $j <= $#{$filelist}; $j++ ) # iterating over file list
314 my $onefile = ${$filelist}[$j];
315 my $gid = $onefile->{'gid'};
317 if ( $gid eq $fileid )
319 $includelink = 1;
320 last;
324 if ( $includelink )
326 push(@newlinklist, $onelink);
330 # iterating over the new list, because of all links with a ShortcutID
332 for ( my $i = 0; $i <= $#{$linklist}; $i++ )
334 my $includelink = 0;
336 my $onelink = ${$linklist}[$i];
338 my $shortcutid = "";
339 if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; }
341 if ( $shortcutid eq "" ) { next; } # A link with a ShortcutID
343 for ( my $j = 0; $j <= $#newlinklist; $j++ ) # iterating over newly created link list
345 my $onefilelink = $newlinklist[$j];
346 my $gid = $onefilelink->{'gid'};
348 if ( $gid eq $shortcutid )
350 $includelink = 1;
351 last;
355 if ( $includelink )
357 push(@newlinklist, $onelink);
361 return \@newlinklist;
364 #####################################################################
365 # Analyzing all directories if they belong to a special package.
366 # A package is described by a list of modules.
367 # Directories are included into the package, if they are needed
368 # by a file or a link included into the package.
369 # Attention: A directory with the flag CREATE, is only included
370 # into the root module:
371 # ($packagename eq $installer::globals::rootmodulegid)
372 #####################################################################
374 sub find_dirs_for_package
376 my ($dirlist, $onepackage) = @_;
378 my @newdirlist = ();
380 for ( my $i = 0; $i <= $#{$dirlist}; $i++ )
382 my $onedir = ${$dirlist}[$i];
383 my $modulesstring = $onedir->{'modules'}; # comma separated modules list
384 my $moduleslist = installer::converter::convert_stringlist_into_array(\$modulesstring, ",");
386 my $includedir = 0;
388 # iterating over all modules of this dir
390 for ( my $j = 0; $j <= $#{$moduleslist}; $j++ )
392 if ( $includedir ) { last; }
393 my $dirmodule = ${$moduleslist}[$j];
394 installer::remover::remove_leading_and_ending_whitespaces(\$dirmodule);
396 # iterating over all modules of the package
398 my $packagemodules = $onepackage->{'allmodules'};
400 for ( my $k = 0; $k <= $#{$packagemodules}; $k++ )
402 my $packagemodule = ${$packagemodules}[$k];
404 if ( $dirmodule eq $packagemodule )
406 $includedir = 1;
407 last;
412 if ( $includedir )
414 push(@newdirlist, $onedir);
418 return \@newdirlist;
421 #####################################################################
422 # Resolving all variables in the packagename.
423 #####################################################################
425 sub resolve_packagevariables
427 my ($packagenameref, $variableshashref, $make_lowercase) = @_;
429 my $key;
431 # Special handling for dictionaries
432 if ( $$packagenameref =~ /-dict-/ )
434 if (exists($variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}) ) { $$packagenameref =~ s/\%UNIXPRODUCTNAME/$variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}/g; }
435 if (exists($variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}) ) { $$packagenameref =~ s/\%BRANDPACKAGEVERSION/$variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}/g; }
438 foreach $key (keys %{$variableshashref})
440 my $value = $variableshashref->{$key};
441 if ( $make_lowercase ) { $value = lc($value); }
442 $$packagenameref =~ s/\%$key/$value/g;
446 #####################################################################
447 # Resolving all variables in the packagename.
448 #####################################################################
450 sub resolve_packagevariables2
452 my ($packagenameref, $variableshashref, $make_lowercase, $isdict ) = @_;
454 my $key;
456 # Special handling for dictionaries
457 if ( $isdict )
459 if (exists($variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}) ) { $$packagenameref =~ s/\%UNIXPRODUCTNAME/$variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}/g; }
460 if (exists($variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}) ) { $$packagenameref =~ s/\%BRANDPACKAGEVERSION/$variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}/g; }
463 foreach $key (keys %{$variableshashref})
465 my $value = $variableshashref->{$key};
466 if ( $make_lowercase ) { $value = lc($value); }
467 $$packagenameref =~ s/\%$key/$value/g;
471 #####################################################################
472 # New packages system.
473 #####################################################################
475 ##################################################################
476 # Controlling the content of the packagelist
477 # 1. Items in @installer::globals::packagelistitems must exist
478 # 2. If a shellscript file is defined, it must exist
479 ##################################################################
481 sub check_packagelist
483 my ($packages) = @_;
485 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "check_packagelist"); }
487 for ( my $i = 0; $i <= $#{$packages}; $i++ )
489 my $onepackage = ${$packages}[$i];
491 my $element;
493 # checking all items that must be defined
495 foreach $element (@installer::globals::packagelistitems)
497 if ( ! exists($onepackage->{$element}) )
499 installer::exiter::exit_program("ERROR in package list: No value for $element !", "check_packagelist");
503 # checking the existence of the script file, if defined
505 if ( $onepackage->{'script'} )
507 my $scriptfile = $onepackage->{'script'};
508 my $gid = $onepackage->{'module'};
509 my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfile, "" , 0);
511 if ( $$fileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find script file $scriptfile for module $gid!", "check_packagelist"); }
513 my $infoline = "$gid: Using script file: \"$$fileref\"!\n";
514 push( @installer::globals::logfileinfo, $infoline);
516 $onepackage->{'script'} = $$fileref;
521 #####################################################################
522 # Reading pack info for one module from packinfo file.
523 #####################################################################
525 sub get_packinfo
527 my ($gid, $filename, $packages, $onelanguage, $islanguagemodule) = @_;
529 my $packagelist = installer::files::read_file($filename);
531 my @allpackages = ();
533 for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
535 my $line = ${$packagelist}[$i];
537 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line
539 if ( $line =~ /^\s*Start\s*$/i ) # a new package definition
541 my %onepackage = ();
543 my $counter = $i + 1;
545 while (!( ${$packagelist}[$counter] =~ /^\s*End\s*$/i ))
547 if ( ${$packagelist}[$counter] =~ /^\s*(\S+)\s*\=\s*\"(.*)\"/ )
549 my $key = $1;
550 my $value = $2;
551 $onepackage{$key} = $value;
554 $counter++;
557 $onepackage{'islanguagemodule'} = $islanguagemodule;
558 if ( $islanguagemodule )
560 my $saveonelanguage = $onelanguage;
561 $saveonelanguage =~ s/_/-/g;
562 $onepackage{'language'} = $saveonelanguage;
565 push(@allpackages, \%onepackage);
569 # looking for the packinfo with the correct gid
571 my $foundgid = 0;
572 my $onepackage;
573 foreach $onepackage (@allpackages)
575 # Adding the language to the module gid for LanguagePacks !
576 # Making the module gid language specific: gid_Module_Root -> gir_Module_Root_pt_BR (as defined in scp2)
577 if ( $onelanguage ne "" ) { $onepackage->{'module'} = $onepackage->{'module'} . "_$onelanguage"; }
579 if ( $onepackage->{'module'} eq $gid )
581 # Resolving the language identifier
582 my $onekey;
583 foreach $onekey ( keys %{$onepackage} )
585 # Some keys require "-" instead of "_" for example in "en-US". All package names do not use underlines.
586 my $locallang = $onelanguage;
587 if (( $onekey eq "solarispackagename" ) ||
588 ( $onekey eq "solarisrequires" ) ||
589 ( $onekey eq "packagename" ) ||
590 ( $onekey eq "requires" )) { $locallang =~ s/_/-/g; } # avoiding illegal package abbreviation
591 $onepackage->{$onekey} =~ s/\%LANGUAGESTRING/$locallang/g;
594 # Saving the language for the package
595 my $lang = $onelanguage;
596 $lang =~ s/_/-/g;
597 $onepackage->{'specificlanguage'} = $lang;
599 push(@{$packages}, $onepackage);
600 $foundgid = 1;
601 last;
605 if ( ! $foundgid )
607 installer::exiter::exit_program("ERROR: Could not find package info for module $gid in file \"$filename\"!", "get_packinfo");
611 #####################################################################
612 # Collecting all packages from scp project.
613 #####################################################################
615 sub collectpackages
617 my ( $allmodules, $languagesarrayref ) = @_;
619 installer::logger::include_header_into_logfile("Collecting packages:");
621 my @packages = ();
622 my %gid_analyzed = ();
624 my $onemodule;
625 foreach $onemodule ( @{$allmodules} )
627 if ( $onemodule->{'PackageInfo'} ) # this is a package module!
629 my $modulegid = $onemodule->{'gid'};
631 my $styles = "";
632 if ( $onemodule->{'Styles'} ) { $styles = $onemodule->{'Styles'}; }
634 # checking modules with style LANGUAGEMODULE
635 my $islanguagemodule = 0;
636 my $onelanguage = "";
637 if ( $styles =~ /\bLANGUAGEMODULE\b/ )
639 $islanguagemodule = 1;
640 $onelanguage = $onemodule->{'Language'}; # already checked, that it is set.
641 $onelanguage =~ s/-/_/g; # pt-BR -> pt_BR in scp
644 # Modules in different languages are listed more than once in multilingual installation sets
645 if ( exists($gid_analyzed{$modulegid}) ) { next; }
646 $gid_analyzed{$modulegid} = 1;
648 my $packinfofile = $onemodule->{'PackageInfo'};
650 # The file with package information has to be found in path list
651 my $fileref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$packinfofile, "" , 0);
653 if ( $$fileref eq "" ) { installer::exiter::exit_program("ERROR: Could not find file $packinfofile for module $modulegid!", "collectpackages"); }
655 my $infoline = "$modulegid: Using packinfo: \"$$fileref\"!\n";
656 push( @installer::globals::logfileinfo, $infoline);
658 get_packinfo($modulegid, $$fileref, \@packages, $onelanguage, $islanguagemodule);
662 return \@packages;
665 #####################################################################
666 # Printing packages content for debugging purposes
667 #####################################################################
669 sub log_packages_content
671 my ($packages) = @_;
673 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }
675 installer::logger::include_header_into_logfile("Logging packages content:");
677 my $infoline = "";
679 for ( my $i = 0; $i <= $#{$packages}; $i++ )
681 my $onepackage = ${$packages}[$i];
683 # checking all items that must be defined
685 $infoline = "Package $onepackage->{'module'}\n";
686 push(@installer::globals::logfileinfo, $infoline);
688 my $key;
689 foreach $key (sort keys %{$onepackage})
691 if ( $key =~ /^\s*\;/ ) { next; }
693 if ( $key eq "allmodules" )
695 $infoline = "\t$key:\n";
696 push(@installer::globals::logfileinfo, $infoline);
697 my $onemodule;
698 foreach $onemodule ( @{$onepackage->{$key}} )
700 $infoline = "\t\t$onemodule\n";
701 push(@installer::globals::logfileinfo, $infoline);
704 else
706 $infoline = "\t$key: $onepackage->{$key}\n";
707 push(@installer::globals::logfileinfo, $infoline);
711 $infoline = "\n";
712 push(@installer::globals::logfileinfo, $infoline);
717 #####################################################################
718 # Creating assignments from modules to destination paths.
719 # This is required for logging in fileinfo file. Otherwise
720 # the complete destination file would not be known in file list.
721 # Saved in %installer::globals::moduledestination
722 #####################################################################
724 sub create_module_destination_hash
726 my ($packages, $allvariables) = @_;
728 for ( my $i = 0; $i <= $#{$packages}; $i++ )
730 my $onepackage = ${$packages}[$i];
732 my $defaultdestination = $onepackage->{'destpath'};
733 resolve_packagevariables(\$defaultdestination, $allvariables, 1);
734 if ( $^O =~ /darwin/i ) { $defaultdestination =~ s/\/opt\//\/Applications\//; }
736 foreach my $onemodule ( @{$onepackage->{'allmodules'}} )
738 $installer::globals::moduledestination{$onemodule} = $defaultdestination;
743 #####################################################################
744 # Adding the default paths into the files collector for Unixes.
745 # This is necessary to know the complete destination path in
746 # fileinfo log file.
747 #####################################################################
749 sub add_defaultpaths_into_filescollector
751 my ($allfiles) = @_;
753 for ( my $i = 0; $i <= $#{$allfiles}; $i++ )
755 my $onefile = ${$allfiles}[$i];
757 if ( ! $onefile->{'destination'} ) { installer::exiter::exit_program("ERROR: No destination found at file $onefile->{'gid'}!", "add_defaultpaths_into_filescollector"); }
758 my $destination = $onefile->{'destination'};
760 if ( ! $onefile->{'modules'} ) { installer::exiter::exit_program("ERROR: No modules found at file $onefile->{'gid'}!", "add_defaultpaths_into_filescollector"); }
761 my $module = $onefile->{'modules'};
762 # If modules contains a list of modules, only taking the first one.
763 if ( $module =~ /^\s*(.*?)\,/ ) { $module = $1; }
765 if ( ! exists($installer::globals::moduledestination{$module}) ) { installer::exiter::exit_program("ERROR: No default destination path found for module $module!", "add_defaultpaths_into_filescollector"); }
766 my $defaultpath = $installer::globals::moduledestination{$module};
767 $defaultpath =~ s/\/\s*$//; # removing ending slashes
768 my $fulldestpath = $defaultpath . $installer::globals::separator . $destination;
770 $onefile->{'fulldestpath'} = $fulldestpath;
774 #####################################################################
775 # Creating list of cabinet files from packages
776 #####################################################################
778 sub prepare_cabinet_files
780 my ($packages, $allvariables) = @_;
782 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }
784 installer::logger::include_header_into_logfile("Preparing cabinet files:");
786 my $infoline = "";
788 for ( my $i = 0; $i <= $#{$packages}; $i++ )
790 my $onepackage = ${$packages}[$i];
792 my $cabinetfile = "$onepackage->{'packagename'}\.cab";
794 resolve_packagevariables(\$cabinetfile, $allvariables, 0);
796 $installer::globals::allcabinets{$cabinetfile} = 1;
798 # checking all items that must be defined
800 $infoline = "Package $onepackage->{'module'}\n";
801 push(@installer::globals::logfileinfo, $infoline);
803 # Assigning the cab file to the module and also to all corresponding sub modules
805 my $onemodule;
806 foreach $onemodule ( @{$onepackage->{'allmodules'}} )
808 if ( ! exists($installer::globals::allcabinetassigns{$onemodule}) )
810 $installer::globals::allcabinetassigns{$onemodule} = $cabinetfile;
812 else
814 my $infoline = "Warning: Already existing assignment: $onemodule : $installer::globals::allcabinetassigns{$onemodule}\n";
815 push(@installer::globals::logfileinfo, $infoline);
816 $infoline = "Ignoring further assignment: $onemodule : $cabinetfile\n";
817 push(@installer::globals::logfileinfo, $infoline);
823 #####################################################################
824 # Logging assignments of cabinet files
825 #####################################################################
827 sub log_cabinet_assignments
829 installer::logger::include_header_into_logfile("Logging cabinet files:");
831 my $infoline = "List of cabinet files:\n";
832 push(@installer::globals::logfileinfo, $infoline);
834 my $key;
835 foreach $key ( sort keys %installer::globals::allcabinets ) { push(@installer::globals::logfileinfo, "\t$key\n"); }
837 $infoline = "\nList of assignments from modules to cabinet files:\n";
838 push(@installer::globals::logfileinfo, $infoline);
840 foreach $key ( sort keys %installer::globals::allcabinetassigns ) { push(@installer::globals::logfileinfo, "\t$key : $installer::globals::allcabinetassigns{$key}\n"); }