1 #*************************************************************************
3 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 # Copyright 2008 by Sun Microsystems, Inc.
7 # OpenOffice.org - a multi-platform office productivity suite
9 # $RCSfile: packagelist.pm,v $
13 # This file is part of OpenOffice.org.
15 # OpenOffice.org is free software: you can redistribute it and/or modify
16 # it under the terms of the GNU Lesser General Public License version 3
17 # only, as published by the Free Software Foundation.
19 # OpenOffice.org is distributed in the hope that it will be useful,
20 # but WITHOUT ANY WARRANTY; without even the implied warranty of
21 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 # GNU Lesser General Public License version 3 for more details
23 # (a copy is included in the LICENSE file that accompanied this code).
25 # You should have received a copy of the GNU Lesser General Public License
26 # version 3 along with OpenOffice.org. If not, see
27 # <http://www.openoffice.org/license.html>
28 # for a copy of the LGPLv3 License.
30 #*************************************************************************
32 package installer
::packagelist
;
34 use installer
::converter
;
35 use installer
::exiter
;
36 use installer
::globals
;
37 use installer
::remover
;
38 use installer
::scriptitems
;
40 ########################################
41 # Check existence of module
42 ########################################
44 sub check_module_existence
46 my ($onegid, $moduleslist) = @_;
50 for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
52 my $gid = ${$moduleslist}[$i]->{'gid'};
54 if ( $gid eq $onegid )
64 ###################################################
65 # Analyzing the gids, defined in the packagelist
66 ###################################################
70 my ($packagelist, $moduleslist) = @_;
74 my $moduleshash = get_module_hash
($moduleslist);
76 for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
78 my $onepackage = ${$packagelist}[$i];
80 my $onegid = $onepackage->{'module'};
82 installer
::remover
::remove_leading_and_ending_whitespaces
(\
$onegid);
84 my $moduleexists = check_module_existence
($onegid, $moduleslist);
86 if ( ! $moduleexists ) { next; }
90 push(@allmodules, $onegid);
92 # get_children($moduleslist, $onegid, \@allmodules);
93 get_children_with_hash
($moduleshash, $onegid, \
@allmodules);
95 $onepackage->{'allmodules'} = \
@allmodules;
97 push(@allpackages, $onepackage);
100 return \
@allpackages;
103 ###################################################
104 # Creating a hash, that contains the module gids
105 # as keys and the parentids as values
106 ###################################################
110 my ($moduleslist) = @_;
114 for ( my $i = 0; $i <= $#{$moduleslist}; $i++ )
116 my $gid = ${$moduleslist}[$i]->{'gid'};
117 # Containing only modules with parent. Root modules can be ignored.
118 if ( ${$moduleslist}[$i]->{'ParentID'} ) { $modulehash{$gid} = ${$moduleslist}[$i]->{'ParentID'}; }
124 ########################################################
125 # Recursively defined procedure to order
126 # modules and directories
127 ########################################################
129 sub get_children_with_hash
131 my ($modulehash, $parentgid, $newitemorder) = @_;
133 foreach my $gid ( keys %{$modulehash} )
135 my $parent = $modulehash->{$gid};
137 if ( $parent eq $parentgid )
139 push(@
{$newitemorder}, $gid);
141 get_children_with_hash
($modulehash, $parent, $newitemorder); # recursive!
146 ########################################################
147 # Recursively defined procedure to order
148 # modules and directories
149 ########################################################
153 my ($allitems, $startparent, $newitemorder) = @_;
155 for ( my $i = 0; $i <= $#{$allitems}; $i++ )
157 my $gid = ${$allitems}[$i]->{'gid'};
159 if ( ${$allitems}[$i]->{'ParentID'} ) { $parent = ${$allitems}[$i]->{'ParentID'}; }
161 if ( $parent eq $startparent )
163 push(@
{$newitemorder}, $gid);
165 get_children
($allitems, $parent, $newitemorder); # recursive!
170 #####################################################################
171 # All modules below a defined gid_Module_A are collected now for
172 # each modules defined in the packagelist. Now the modules have
173 # to be removed, that are part of more than one package.
174 #####################################################################
176 sub remove_multiple_modules_packages
178 my ($allpackagemodules) = @_;
180 # iterating over all packages
182 for ( my $i = 0; $i <= $#{$allpackagemodules}; $i++ )
184 my $onepackage = ${$allpackagemodules}[$i];
185 my $allmodules = $onepackage->{'allmodules'};
187 # print "Modules below $onepackage->{'module'}: $#{$allmodules}\n";
189 # Comparing each package, with all following packages. If a
190 # gid for the module is part of more than one package, it is
191 # removed if the number of modules in the package is greater
192 # in the current package than in the compare package.
194 # Taking all modules from package $i
196 my $packagecount = $#{$allmodules};
198 my @optimizedpackage = ();
200 # iterating over all modules of this package
202 for ( my $j = 0; $j <= $#{$allmodules}; $j++ )
204 my $onemodule = ${$allmodules}[$j]; # this is the module, that shall be removed or not
206 my $put_module_into_new_package = 1;
208 # iterating over all other packages
210 for ( my $k = 0; $k <= $#{$allpackagemodules}; $k++ )
212 if ( $k == $i ) { next; } # not comparing equal module
214 if (! $put_module_into_new_package) { next; } # do not compare, if already found
216 my $comparepackage = ${$allpackagemodules}[$k];
217 my $allcomparemodules = $comparepackage->{'allmodules'};
219 my $comparepackagecount = $#{$allcomparemodules};
221 # modules will only be removed from packages, that have more modules
222 # than the compare package
224 if ( $packagecount <= $comparepackagecount ) { next; } # nothing to do, take next package
226 # iterating over all modules of this package
228 for ( my $m = 0; $m <= $#{$allcomparemodules}; $m++ )
230 my $onecomparemodule = ${$allcomparemodules}[$m];
232 if ( $onemodule eq $onecomparemodule ) # this $onemodule has to be removed
234 $put_module_into_new_package = 0;
239 if ( $put_module_into_new_package )
241 push(@optimizedpackage, $onemodule)
245 $onepackage->{'allmodules'} = \
@optimizedpackage;
248 # for ( my $i = 0; $i <= $#{$allpackagemodules}; $i++ )
250 # my $onepackage = ${$allpackagemodules}[$i];
251 # my $allmodules = $onepackage->{'allmodules'};
252 # print "New: Modules below $onepackage->{'module'}: $#{$allmodules}\n";
257 #####################################################################
258 # Analyzing all files if they belong to a special package.
259 # A package is described by a list of modules.
260 #####################################################################
262 sub find_files_for_package
264 my ($filelist, $onepackage) = @_;
266 my @newfilelist = ();
268 for ( my $i = 0; $i <= $#{$filelist}; $i++ )
270 my $onefile = ${$filelist}[$i];
271 my $modulesstring = $onefile->{'modules'}; # comma separated modules list
272 my $moduleslist = installer
::converter
::convert_stringlist_into_array
(\
$modulesstring, ",");
276 # iterating over all modules of this file
278 for ( my $j = 0; $j <= $#{$moduleslist}; $j++ )
280 if ( $includefile ) { next; }
281 my $filemodule = ${$moduleslist}[$j];
282 installer
::remover
::remove_leading_and_ending_whitespaces
(\
$filemodule);
284 # iterating over all modules of the package
286 my $packagemodules = $onepackage->{'allmodules'};
288 for ( my $k = 0; $k <= $#{$packagemodules}; $k++ )
290 if ( $includefile ) { next; }
291 my $packagemodule = ${$packagemodules}[$k];
293 if ( $filemodule eq $packagemodule )
303 push(@newfilelist, $onefile);
307 return \
@newfilelist;
310 #####################################################################
311 # Analyzing all links if they belong to a special package.
312 # A package is described by a list of modules.
313 # A link is inserted into the package, if the corresponding
314 # file is also inserted.
315 #####################################################################
317 sub find_links_for_package
319 my ($linklist, $filelist) = @_;
321 # First looking for all links with a FileID.
322 # Then looking for all links with a ShortcutID.
324 my @newlinklist = ();
326 for ( my $i = 0; $i <= $#{$linklist}; $i++ )
330 my $onelink = ${$linklist}[$i];
333 if ( $onelink->{'FileID'} ) { $fileid = $onelink->{'FileID'}; }
335 if ( $fileid eq "" ) { next; } # A link with a ShortcutID
337 for ( my $j = 0; $j <= $#{$filelist}; $j++ ) # iterating over file list
339 my $onefile = ${$filelist}[$j];
340 my $gid = $onefile->{'gid'};
342 if ( $gid eq $fileid )
351 push(@newlinklist, $onelink);
355 # iterating over the new list, because of all links with a ShortcutID
357 for ( my $i = 0; $i <= $#{$linklist}; $i++ )
361 my $onelink = ${$linklist}[$i];
364 if ( $onelink->{'ShortcutID'} ) { $shortcutid = $onelink->{'ShortcutID'}; }
366 if ( $shortcutid eq "" ) { next; } # A link with a ShortcutID
368 for ( my $j = 0; $j <= $#newlinklist; $j++ ) # iterating over newly created link list
370 my $onefilelink = $newlinklist[$j];
371 my $gid = $onefilelink->{'gid'};
373 if ( $gid eq $shortcutid )
382 push(@newlinklist, $onelink);
386 return \
@newlinklist;
389 #####################################################################
390 # Analyzing all directories if they belong to a special package.
391 # A package is described by a list of modules.
392 # Directories are included into the package, if they are needed
393 # by a file or a link included into the package.
394 # Attention: A directory with the flag CREATE, is only included
395 # into the root module:
396 # ($packagename eq $installer::globals::rootmodulegid)
397 #####################################################################
399 sub find_dirs_for_package
401 my ($dirlist, $onepackage) = @_;
405 for ( my $i = 0; $i <= $#{$dirlist}; $i++ )
407 my $onedir = ${$dirlist}[$i];
408 my $modulesstring = $onedir->{'modules'}; # comma separated modules list
409 my $moduleslist = installer
::converter
::convert_stringlist_into_array
(\
$modulesstring, ",");
413 # iterating over all modules of this dir
415 for ( my $j = 0; $j <= $#{$moduleslist}; $j++ )
417 if ( $includedir ) { last; }
418 my $dirmodule = ${$moduleslist}[$j];
419 installer
::remover
::remove_leading_and_ending_whitespaces
(\
$dirmodule);
421 # iterating over all modules of the package
423 my $packagemodules = $onepackage->{'allmodules'};
425 for ( my $k = 0; $k <= $#{$packagemodules}; $k++ )
427 my $packagemodule = ${$packagemodules}[$k];
429 if ( $dirmodule eq $packagemodule )
439 push(@newdirlist, $onedir);
446 #####################################################################
447 # Resolving all variables in the packagename.
448 #####################################################################
450 sub resolve_packagevariables
452 my ($packagenameref, $variableshashref, $make_lowercase) = @_;
456 # Special handling for dictionaries
457 if ( $$packagenameref =~ /-dict-/ )
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 # Resolving all variables in the packagename.
473 #####################################################################
475 sub resolve_packagevariables2
477 my ($packagenameref, $variableshashref, $make_lowercase, $isdict ) = @_;
481 # Special handling for dictionaries
484 if (exists($variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}) ) { $$packagenameref =~ s/\%UNIXPRODUCTNAME/$variableshashref->{'DICTIONARYUNIXPRODUCTNAME'}/g; }
485 if (exists($variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}) ) { $$packagenameref =~ s/\%BRANDPACKAGEVERSION/$variableshashref->{'DICTIONARYBRANDPACKAGEVERSION'}/g; }
488 foreach $key (keys %{$variableshashref})
490 my $value = $variableshashref->{$key};
491 if ( $make_lowercase ) { $value = lc($value); }
492 $$packagenameref =~ s/\%$key/$value/g;
496 #####################################################################
497 # New packages system.
498 #####################################################################
500 ##################################################################
501 # Controlling the content of the packagelist
502 # 1. Items in @installer::globals::packagelistitems must exist
503 # 2. If a shellscript file is defined, it must exist
504 ##################################################################
506 sub check_packagelist
510 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "check_packagelist"); }
512 for ( my $i = 0; $i <= $#{$packages}; $i++ )
514 my $onepackage = ${$packages}[$i];
518 # checking all items that must be defined
520 foreach $element (@installer::globals
::packagelistitems
)
522 if ( ! exists($onepackage->{$element}) )
524 installer
::exiter
::exit_program
("ERROR in package list: No value for $element !", "check_packagelist");
528 # checking the existence of the script file, if defined
530 if ( $onepackage->{'script'} )
532 my $scriptfile = $onepackage->{'script'};
533 my $gid = $onepackage->{'module'};
534 my $fileref = installer
::scriptitems
::get_sourcepath_from_filename_and_includepath
(\
$scriptfile, "" , 0);
536 if ( $$fileref eq "" ) { installer
::exiter
::exit_program
("ERROR: Could not find script file $scriptfile for module $gid!", "check_packagelist"); }
538 my $infoline = "$gid: Using script file: \"$$fileref\"!\n";
539 push( @installer::globals
::logfileinfo
, $infoline);
541 $onepackage->{'script'} = $$fileref;
546 #####################################################################
547 # Reading pack info for one module from packinfo file.
548 #####################################################################
552 my ($gid, $filename, $packages, $onelanguage, $islanguagemodule) = @_;
554 my $packagelist = installer
::files
::read_file
($filename);
556 my @allpackages = ();
558 for ( my $i = 0; $i <= $#{$packagelist}; $i++ )
560 my $line = ${$packagelist}[$i];
562 if ( $line =~ /^\s*\#/ ) { next; } # this is a comment line
564 if ( $line =~ /^\s*Start\s*$/i ) # a new package definition
568 my $counter = $i + 1;
570 while (!( ${$packagelist}[$counter] =~ /^\s*End\s*$/i ))
572 if ( ${$packagelist}[$counter] =~ /^\s*(\S+)\s*\=\s*\"(.*)\"/ )
576 $onepackage{$key} = $value;
582 $onepackage{'islanguagemodule'} = $islanguagemodule;
583 if ( $islanguagemodule )
585 $saveonelanguage = $onelanguage;
586 $saveonelanguage =~ s/_/-/g;
587 $onepackage{'language'} = $saveonelanguage;
590 push(@allpackages, \
%onepackage);
594 # looking for the packinfo with the correct gid
598 foreach $onepackage (@allpackages)
600 # Adding the language to the module gid for LanguagePacks !
601 # Making the module gid language specific: gid_Module_Root -> gir_Module_Root_pt_BR (as defined in scp2)
602 if ( $onelanguage ne "" ) { $onepackage->{'module'} = $onepackage->{'module'} . "_$onelanguage"; }
604 if ( $onepackage->{'module'} eq $gid )
606 # Resolving the language identifier
608 foreach $onekey ( keys %{$onepackage} )
610 # Some keys require "-" instead of "_" for example in "en-US". All package names do not use underlines.
611 my $locallang = $onelanguage;
612 if (( $onekey eq "solarispackagename" ) ||
613 ( $onekey eq "solarisrequires" ) ||
614 ( $onekey eq "packagename" ) ||
615 ( $onekey eq "requires" )) { $locallang =~ s/_/-/g; } # avoiding illegal package abbreviation
616 $onepackage->{$onekey} =~ s/\%LANGUAGESTRING/$locallang/g;
619 # Saving the language for the package
620 my $lang = $onelanguage;
622 $onepackage->{'specificlanguage'} = $lang;
624 push(@
{$packages}, $onepackage);
632 installer
::exiter
::exit_program
("ERROR: Could not find package info for module $gid in file \"$filename\"!", "get_packinfo");
636 #####################################################################
637 # Collecting all packages from scp project.
638 #####################################################################
642 my ( $allmodules, $languagesarrayref ) = @_;
644 installer
::logger
::include_header_into_logfile
("Collecting packages:");
647 my %gid_analyzed = ();
650 foreach $onemodule ( @
{$allmodules} )
652 my $packageinfo = "PackageInfo";
653 if (( $installer::globals
::tab
) && ( $onemodule->{"TabPackageInfo"} )) { $packageinfo = "TabPackageInfo" }
655 if ( $onemodule->{$packageinfo} ) # this is a package module!
657 my $modulegid = $onemodule->{'gid'};
659 # Only collecting modules with correct language for language packs
660 # if ( $installer::globals::languagepack ) { if ( ! ( $modulegid =~ /_$onelanguage\s*$/ )) { next; } }
661 # Resetting language, if this is no language pack
662 # if ( ! $installer::globals::languagepack ) { $onelanguage = ""; }
665 if ( $onemodule->{'Styles'} ) { $styles = $onemodule->{'Styles'}; }
667 # checking modules with style LANGUAGEMODULE
668 my $islanguagemodule = 0;
669 my $onelanguage = "";
670 if ( $styles =~ /\bLANGUAGEMODULE\b/ )
672 $islanguagemodule = 1;
673 $onelanguage = $onemodule->{'Language'}; # already checked, that it is set.
674 $onelanguage =~ s/-/_/g; # pt-BR -> pt_BR in scp
677 # Modules in different languages are listed more than once in multilingual installation sets
678 if ( exists($gid_analyzed{$modulegid}) ) { next; }
679 $gid_analyzed{$modulegid} = 1;
681 my $packinfofile = $onemodule->{$packageinfo};
683 # The file with package information has to be found in path list
684 my $fileref = installer
::scriptitems
::get_sourcepath_from_filename_and_includepath
(\
$packinfofile, "" , 0);
686 if ( $$fileref eq "" ) { installer
::exiter
::exit_program
("ERROR: Could not find file $packinfofile for module $modulegid!", "collectpackages"); }
688 my $infoline = "$modulegid: Using packinfo: \"$$fileref\"!\n";
689 push( @installer::globals
::logfileinfo
, $infoline);
691 get_packinfo
($modulegid, $$fileref, \
@packages, $onelanguage, $islanguagemodule);
698 #####################################################################
699 # Printing packages content for debugging purposes
700 #####################################################################
702 sub log_packages_content
706 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }
708 installer
::logger
::include_header_into_logfile
("Logging packages content:");
712 for ( my $i = 0; $i <= $#{$packages}; $i++ )
714 my $onepackage = ${$packages}[$i];
716 # checking all items that must be defined
718 $infoline = "Package $onepackage->{'module'}\n";
719 push(@installer::globals
::logfileinfo
, $infoline);
722 foreach $key (sort keys %{$onepackage})
724 if ( $key =~ /^\s*\;/ ) { next; }
726 if ( $key eq "allmodules" )
728 $infoline = "\t$key:\n";
729 push(@installer::globals
::logfileinfo
, $infoline);
731 foreach $onemodule ( @
{$onepackage->{$key}} )
733 $infoline = "\t\t$onemodule\n";
734 push(@installer::globals
::logfileinfo
, $infoline);
739 $infoline = "\t$key: $onepackage->{$key}\n";
740 push(@installer::globals
::logfileinfo
, $infoline);
745 push(@installer::globals
::logfileinfo
, $infoline);
750 #####################################################################
751 # Creating assignments from modules to destination pathes.
752 # This is required for logging in fileinfo file. Otherwise
753 # the complete destination file would not be known in file list.
754 # Saved in %installer::globals::moduledestination
755 #####################################################################
757 sub create_module_destination_hash
759 my ($packages, $allvariables) = @_;
761 for ( my $i = 0; $i <= $#{$packages}; $i++ )
763 my $onepackage = ${$packages}[$i];
765 my $defaultdestination = $onepackage->{'destpath'};
766 resolve_packagevariables
(\
$defaultdestination, $allvariables, 1);
767 if ( $^O
=~ /darwin/i ) { $defaultdestination =~ s/\/opt\//\/Applications\
//; }
769 foreach my $onemodule ( @
{$onepackage->{'allmodules'}} )
771 $installer::globals
::moduledestination
{$onemodule} = $defaultdestination;
776 #####################################################################
777 # Adding the default pathes into the files collector for Unixes.
778 # This is necessary to know the complete destination path in
780 #####################################################################
782 sub add_defaultpathes_into_filescollector
786 for ( my $i = 0; $i <= $#{$allfiles}; $i++ )
788 my $onefile = ${$allfiles}[$i];
790 if ( ! $onefile->{'destination'} ) { installer
::exiter
::exit_program
("ERROR: No destination found at file $onefile->{'gid'}!", "add_defaultpathes_into_filescollector"); }
791 my $destination = $onefile->{'destination'};
793 if ( ! $onefile->{'modules'} ) { installer
::exiter
::exit_program
("ERROR: No modules found at file $onefile->{'gid'}!", "add_defaultpathes_into_filescollector"); }
794 my $module = $onefile->{'modules'};
795 # If modules contains a list of modules, only taking the first one.
796 if ( $module =~ /^\s*(.*?)\,/ ) { $module = $1; }
798 if ( ! exists($installer::globals
::moduledestination
{$module}) ) { installer
::exiter
::exit_program
("ERROR: No default destination path found for module $module!", "add_defaultpathes_into_filescollector"); }
799 my $defaultpath = $installer::globals
::moduledestination
{$module};
800 $defaultpath =~ s/\/\s*$//; # removing ending slashes
801 my $fulldestpath = $defaultpath . $installer::globals
::separator
. $destination;
803 $onefile->{'fulldestpath'} = $fulldestpath;
807 #####################################################################
808 # Creating list of cabinet files from packages
809 #####################################################################
811 sub prepare_cabinet_files
813 my ($packages, $allvariables) = @_;
815 if ( ! ( $#{$packages} > -1 )) { installer::exiter::exit_program("ERROR: No packages defined!", "print_content"); }
817 installer
::logger
::include_header_into_logfile
("Preparing cabinet files:");
821 for ( my $i = 0; $i <= $#{$packages}; $i++ )
823 my $onepackage = ${$packages}[$i];
825 my $cabinetfile = "$onepackage->{'packagename'}\.cab";
827 resolve_packagevariables
(\
$cabinetfile, $allvariables, 0);
829 $installer::globals
::allcabinets
{$cabinetfile} = 1;
831 # checking all items that must be defined
833 $infoline = "Package $onepackage->{'module'}\n";
834 push(@installer::globals
::logfileinfo
, $infoline);
836 # Assigning the cab file to the module and also to all corresponding sub modules
839 foreach $onemodule ( @
{$onepackage->{'allmodules'}} )
841 if ( ! exists($installer::globals
::allcabinetassigns
{$onemodule}) )
843 $installer::globals
::allcabinetassigns
{$onemodule} = $cabinetfile;
847 my $infoline = "Warning: Already existing assignment: $onemodule : $installer::globals::allcabinetassigns{$onemodule}\n";
848 push(@installer::globals
::logfileinfo
, $infoline);
849 $infoline = "Ignoring further assignment: $onemodule : $cabinetfile\n";
850 push(@installer::globals
::logfileinfo
, $infoline);
856 #####################################################################
857 # Logging assignments of cabinet files
858 #####################################################################
860 sub log_cabinet_assignments
862 installer
::logger
::include_header_into_logfile
("Logging cabinet files:");
864 my $infoline = "List of cabinet files:\n";
865 push(@installer::globals
::logfileinfo
, $infoline);
868 foreach $key ( sort keys %installer::globals
::allcabinets
) { push(@installer::globals
::logfileinfo
, "\t$key\n"); }
870 $infoline = "\nList of assignments from modules to cabinet files:\n";
871 push(@installer::globals
::logfileinfo
, $infoline);
873 foreach $key ( sort keys %installer::globals
::allcabinetassigns
) { push(@installer::globals
::logfileinfo
, "\t$key : $installer::globals::allcabinetassigns{$key}\n"); }