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::windows::directory; 29 30use installer::exiter; 31use installer::files; 32use installer::globals; 33use installer::pathanalyzer; 34use installer::windows::idtglobal; 35use installer::windows::msiglobal; 36 37############################################################## 38# Collecting all directory trees in global hash 39############################################################## 40 41sub collectdirectorytrees 42{ 43 my ( $directoryref ) = @_; 44 45 for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) 46 { 47 my $onedir = ${$directoryref}[$i]; 48 my $styles = ""; 49 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 50 51 if ( $styles ne "" ) 52 { 53 foreach my $treestyle ( keys %installer::globals::treestyles ) 54 { 55 if ( $styles =~ /\b$treestyle\b/ ) 56 { 57 my $hostname = $onedir->{'HostName'}; 58 # -> hostname is the key, the style the value! 59 $installer::globals::hostnametreestyles{$hostname} = $treestyle; 60 } 61 } 62 } 63 } 64} 65 66############################################################## 67# Overwriting global programfilesfolder, if required 68############################################################## 69 70sub overwrite_programfilesfolder 71{ 72 my ( $allvariables ) = @_; 73 74 if ( $allvariables->{'PROGRAMFILESFOLDERNAME'} ) 75 { 76 $installer::globals::programfilesfolder = $allvariables->{'PROGRAMFILESFOLDERNAME'}; 77 } 78} 79 80############################################################## 81# Maximum length of directory name is 72. 82# Taking care of underlines, which are the separator. 83############################################################## 84 85sub make_short_dir_version 86{ 87 my ($longstring) = @_; 88 89 my $shortstring = ""; 90 my $cutlength = 60; 91 my $length = 5; # So the directory can still be recognized 92 my $longstring_save = $longstring; 93 94 # Splitting the string at each "underline" and allowing only $length characters per directory name. 95 # Checking also uniqueness and length. 96 97 my $stringarray = installer::converter::convert_stringlist_into_array_without_newline(\$longstring, "_"); 98 99 foreach my $onestring ( @{$stringarray} ) 100 { 101 my $partstring = ""; 102 103 if ( $onestring =~ /\-/ ) 104 { 105 my $localstringarray = installer::converter::convert_stringlist_into_array_without_newline(\$onestring, "-"); 106 foreach my $onelocalstring ( @{$localstringarray} ) 107 { 108 if ( length($onelocalstring) > $length ) { $onelocalstring = substr($onelocalstring, 0, $length); } 109 $partstring = $partstring . "-" . $onelocalstring; 110 } 111 $partstring =~ s/^\s*\-//; 112 } 113 else 114 { 115 if ( length($onestring) > $length ) { $partstring = substr($onestring, 0, $length); } 116 else { $partstring = $onestring; } 117 } 118 119 $shortstring = $shortstring . "_" . $partstring; 120 } 121 122 $shortstring =~ s/^\s*\_//; 123 124 # Setting unique ID to each directory 125 # No counter allowed, process must be absolute reproducable due to patch creation process. 126 127 # chomp(my $id = `echo $longstring_save | md5sum | sed -e "s/ .*//g"`); # Very, very slow 128 # my $subid = substr($id, 0, 9); # taking only the first 9 digits 129 130 my $subid = installer::windows::msiglobal::calculate_id($longstring_save, 9); # taking only the first 9 digits 131 132 if ( length($shortstring) > $cutlength ) { $shortstring = substr($shortstring, 0, $cutlength); } 133 134 $shortstring = $shortstring . "_" . $subid; 135 136 return $shortstring; 137} 138 139############################################################## 140# Adding unique directory names to the directory collection 141############################################################## 142 143sub create_unique_directorynames 144{ 145 my ($directoryref, $allvariables) = @_; 146 147 $installer::globals::officeinstalldirectoryset = 0; 148 149 my %completedirhashstep1 = (); 150 my %shortdirhash = (); 151 my %shortdirhashreverse = (); 152 my $infoline = ""; 153 my $errorcount = 0; 154 155 for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) 156 { 157 my $onedir = ${$directoryref}[$i]; 158 my $uniquename = $onedir->{'HostName'}; 159 160 my $styles = ""; 161 if ( $onedir->{'Styles'} ) { $styles = $onedir->{'Styles'}; } 162 163 $uniquename =~ s/^\s*//g; # removing beginning white spaces 164 $uniquename =~ s/\s*$//g; # removing ending white spaces 165 $uniquename =~ s/\s//g; # removing white spaces 166 $uniquename =~ s/\_//g; # removing existing underlines 167 $uniquename =~ s/\.//g; # removing dots in directoryname 168 $uniquename =~ s/OpenOffice/OO/g; 169 170 $uniquename =~ s/\Q$installer::globals::separator\E/\_/g; # replacing slash and backslash with underline 171 172 $uniquename =~ s/_registry/_rgy/g; 173 $uniquename =~ s/_registration/_rgn/g; 174 $uniquename =~ s/_extension/_ext/g; 175 $uniquename =~ s/_frame/_frm/g; 176 $uniquename =~ s/_table/_tbl/g; 177 $uniquename =~ s/_chart/_crt/g; 178 179 # The names after this small changes must still be unique! 180 if ( exists($completedirhashstep1{$uniquename}) ) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 1): \"$uniquename\".", "create_unique_directorynames"); } 181 $completedirhashstep1{$uniquename} = 1; 182 183 # Starting to make unique name for the parent and its directory 184 my $originaluniquename = $uniquename; 185 186 $uniquename = make_short_dir_version($uniquename); 187 188 # Checking if the same directory already exists, but has another short version. 189 if (( exists($shortdirhash{$originaluniquename}) ) && ( $shortdirhash{$originaluniquename} ne $uniquename )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 2A): \"$uniquename\".", "create_unique_directorynames"); } 190 191 # Also checking vice versa 192 # Checking if the same short directory already exists, but has another long version. 193 if (( exists($shortdirhashreverse{$uniquename}) ) && ( $shortdirhashreverse{$uniquename} ne $originaluniquename )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 2B): \"$uniquename\".", "create_unique_directorynames"); } 194 195 # Creating assignment from long to short directory names 196 $shortdirhash{$originaluniquename} = $uniquename; 197 $shortdirhashreverse{$uniquename} = $originaluniquename; 198 199 # Important: The unique parent is generated from the string $originaluniquename (with the use of underlines). 200 201 my $uniqueparentname = $originaluniquename; 202 my $keepparent = 1; 203 204 if ( $uniqueparentname =~ /^\s*(.*)\_(.*?)\s*$/ ) # the underline is now the separator 205 { 206 $uniqueparentname = $1; 207 $keepparent = 0; 208 } 209 else 210 { 211 $uniqueparentname = $installer::globals::programfilesfolder; 212 $keepparent = 1; 213 } 214 215 if ( $styles =~ /\bPROGRAMFILESFOLDER\b/ ) 216 { 217 $uniqueparentname = $installer::globals::programfilesfolder; 218 $keepparent = 1; 219 } 220 if ( $styles =~ /\bCOMMONFILESFOLDER\b/ ) 221 { 222 $uniqueparentname = $installer::globals::commonfilesfolder; 223 $keepparent = 1; 224 } 225 if ( $styles =~ /\bCOMMONAPPDATAFOLDER\b/ ) 226 { 227 $uniqueparentname = $installer::globals::commonappdatafolder; 228 $keepparent = 1; 229 } 230 if ( $styles =~ /\bLOCALAPPDATAFOLDER\b/ ) 231 { 232 $uniqueparentname = $installer::globals::localappdatafolder; 233 $keepparent = 1; 234 } 235 236 if ( $styles =~ /\bSHAREPOINTPATH\b/ ) 237 { 238 $uniqueparentname = "SHAREPOINTPATH"; 239 $installer::globals::usesharepointpath = 1; 240 $keepparent = 1; 241 } 242 243 # also setting short directory name for the parent 244 245 my $originaluniqueparentname = $uniqueparentname; 246 247 if ( ! $keepparent ) 248 { 249 $uniqueparentname = make_short_dir_version($uniqueparentname); 250 } 251 252 # Again checking if the same directory already exists, but has another short version. 253 if (( exists($shortdirhash{$originaluniqueparentname}) ) && ( $shortdirhash{$originaluniqueparentname} ne $uniqueparentname )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 3A): \"$uniqueparentname\".", "create_unique_directorynames"); } 254 255 # Also checking vice versa 256 # Checking if the same short directory already exists, but has another long version. 257 if (( exists($shortdirhashreverse{$uniqueparentname}) ) && ( $shortdirhashreverse{$uniqueparentname} ne $originaluniqueparentname )) { installer::exiter::exit_program("ERROR: Error in packaging process. Unallowed modification of directory name, not unique (step 3B): \"$uniqueparentname\".", "create_unique_directorynames"); } 258 259 $shortdirhash{$originaluniqueparentname} = $uniqueparentname; 260 $shortdirhashreverse{$uniqueparentname} = $originaluniqueparentname; 261 262 # Hyphen not allowed in database 263 $uniquename =~ s/\-/\_/g; # making "-" to "_" 264 $uniqueparentname =~ s/\-/\_/g; # making "-" to "_" 265 266 # And finally setting the values for the directories 267 $onedir->{'uniquename'} = $uniquename; 268 $onedir->{'uniqueparentname'} = $uniqueparentname; 269 270 # setting the installlocation directory 271 if ( $styles =~ /\bISINSTALLLOCATION\b/ ) 272 { 273 if ( $installer::globals::installlocationdirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag ISINSTALLLOCATION alread set: \"$installer::globals::installlocationdirectory\".", "create_unique_directorynames"); } 274 $installer::globals::installlocationdirectory = $uniquename; 275 $installer::globals::installlocationdirectoryset = 1; 276 if ( $installer::globals::installlocationdirectory =~ /oracle_/i ) { $installer::globals::sundirexists = 1; } 277 } 278 279 # setting the sundirectory 280 if ( $styles =~ /\bSUNDIRECTORY\b/ ) 281 { 282 if ( $installer::globals::vendordirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag SUNDIRECTORY alread set: \"$installer::globals::vendordirectory\".", "create_unique_directorynames"); } 283 $installer::globals::vendordirectory = $uniquename; 284 $installer::globals::vendordirectoryset = 1; 285 } 286 } 287} 288 289##################################################### 290# Adding ":." to selected default directory names 291##################################################### 292 293sub check_sourcedir_addon 294{ 295 my ( $onedir, $allvariableshashref ) = @_; 296 297 if (($installer::globals::addchildprojects) || 298 ($installer::globals::patch) || 299 ($installer::globals::languagepack) || 300 ($allvariableshashref->{'CHANGETARGETDIR'})) 301 { 302 my $sourcediraddon = "\:\."; 303 $onedir->{'defaultdir'} = $onedir->{'defaultdir'} . $sourcediraddon; 304 } 305 306} 307 308##################################################### 309# The directory with the style ISINSTALLLOCATION 310# will be replaced by INSTALLLOCATION 311##################################################### 312 313sub set_installlocation_directory 314{ 315 my ( $directoryref, $allvariableshashref ) = @_; 316 317 if ( ! $installer::globals::installlocationdirectoryset ) { installer::exiter::exit_program("ERROR: Directory with flag ISINSTALLLOCATION not set!", "set_installlocation_directory"); } 318 319 for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) 320 { 321 my $onedir = ${$directoryref}[$i]; 322 323 if ( $onedir->{'uniquename'} eq $installer::globals::installlocationdirectory ) 324 { 325 $onedir->{'uniquename'} = "INSTALLLOCATION"; 326 check_sourcedir_addon($onedir, $allvariableshashref); 327 } 328 329 if ( $onedir->{'uniquename'} eq $installer::globals::vendordirectory ) 330 { 331 check_sourcedir_addon($onedir, $allvariableshashref); 332 } 333 334 if ( $onedir->{'uniqueparentname'} eq $installer::globals::installlocationdirectory ) 335 { 336 $onedir->{'uniqueparentname'} = "INSTALLLOCATION"; 337 } 338 } 339} 340 341##################################################### 342# Getting the name of the top level directory. This 343# can have only one letter 344##################################################### 345 346sub get_last_directory_name 347{ 348 my ($completepathref) = @_; 349 350 if ( $$completepathref =~ /^.*[\/\\](.+?)\s*$/ ) 351 { 352 $$completepathref = $1; 353 } 354} 355 356##################################################### 357# Creating the defaultdir for the file Director.idt 358##################################################### 359 360sub create_defaultdir_directorynames 361{ 362 my ($directoryref, $shortdirnamehashref) = @_; 363 364 my @shortnames = (); 365 if ( $installer::globals::updatedatabase ) { @shortnames = values(%{$shortdirnamehashref}); } 366 elsif ( $installer::globals::prepare_winpatch ) { @shortnames = values(%installer::globals::saved83dirmapping); } 367 368 for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) 369 { 370 my $onedir = ${$directoryref}[$i]; 371 my $hostname = $onedir->{'HostName'}; 372 373 $hostname =~ s/\Q$installer::globals::separator\E\s*$//; 374 get_last_directory_name(\$hostname); 375 # installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$hostname); # making program/classes to classes 376 my $uniquename = $onedir->{'uniquename'}; 377 my $shortstring; 378 if (( $installer::globals::updatedatabase ) && ( exists($shortdirnamehashref->{$uniquename}) )) 379 { 380 $shortstring = $shortdirnamehashref->{$uniquename}; 381 } 382 elsif (( $installer::globals::prepare_winpatch ) && ( exists($installer::globals::saved83dirmapping{$uniquename}) )) 383 { 384 $shortstring = $installer::globals::saved83dirmapping{$uniquename}; 385 } 386 else 387 { 388 $shortstring = installer::windows::idtglobal::make_eight_three_conform($hostname, "dir", \@shortnames); 389 } 390 391 my $defaultdir; 392 393 if ( $shortstring eq $hostname ) 394 { 395 $defaultdir = $hostname; 396 } 397 else 398 { 399 $defaultdir = $shortstring . "|" . $hostname; 400 } 401 402 $onedir->{'defaultdir'} = $defaultdir; 403 404 my $fontdir = ""; 405 if ( $onedir->{'Dir'} ) { $fontdir = $onedir->{'Dir'}; } 406 407 my $fontdefaultdir = ""; 408 if ( $onedir->{'defaultdir'} ) { $fontdefaultdir = $onedir->{'defaultdir'}; } 409 410 if (( $fontdir eq "PREDEFINED_OSSYSTEMFONTDIR" ) && ( $fontdefaultdir eq $installer::globals::fontsdirhostname )) 411 { 412 $installer::globals::fontsdirname = $onedir->{'defaultdir'}; 413 $installer::globals::fontsdirparent = $onedir->{'uniqueparentname'}; 414 } 415 } 416} 417 418############################################### 419# Fill content into the directory table 420############################################### 421 422sub create_directorytable_from_collection 423{ 424 my ($directorytableref, $directoryref) = @_; 425 426 for ( my $i = 0; $i <= $#{$directoryref}; $i++ ) 427 { 428 my $onedir = ${$directoryref}[$i]; 429 my $hostname = $onedir->{'HostName'}; 430 my $dir = ""; 431 432 if ( $onedir->{'Dir'} ) { $dir = $onedir->{'Dir'}; } 433 434 if (( $dir eq "PREDEFINED_PROGDIR" ) && ( $hostname eq "" )) { next; } # removing files from root directory 435 436 my $oneline = $onedir->{'uniquename'} . "\t" . $onedir->{'uniqueparentname'} . "\t" . $onedir->{'defaultdir'} . "\n"; 437 438 push(@{$directorytableref}, $oneline); 439 } 440} 441 442############################################### 443# Defining the root installation structure 444############################################### 445 446sub add_root_directories 447{ 448 my ($directorytableref, $allvariableshashref) = @_; 449 450# my $sourcediraddon = ""; 451# if (($installer::globals::addchildprojects) || 452# ($installer::globals::patch) || 453# ($installer::globals::languagepack) || 454# ($allvariableshashref->{'CHANGETARGETDIR'})) 455# { 456# $sourcediraddon = "\:\."; 457# } 458 459 my $oneline = ""; 460 461 if (( ! $installer::globals::patch ) && ( ! $installer::globals::languagepack ) && ( ! $allvariableshashref->{'DONTUSESTARTMENUFOLDER'} )) 462 { 463 my $productname = $allvariableshashref->{'PRODUCTNAME'}; 464 my $productversion = $allvariableshashref->{'PRODUCTVERSION'}; 465 my $baseproductversion = $productversion; 466 467 if (( $installer::globals::prepare_winpatch ) && ( $allvariableshashref->{'BASEPRODUCTVERSION'} )) 468 { 469 $baseproductversion = $allvariableshashref->{'BASEPRODUCTVERSION'}; # for example "2.0" for OOo 470 } 471 472 my $realproductkey = $productname . " " . $productversion; 473 my $productkey = $productname . " " . $baseproductversion; 474 475 if (( $allvariableshashref->{'POSTVERSIONEXTENSION'} ) && ( ! $allvariableshashref->{'DONTUSEEXTENSIONINDEFAULTDIR'} )) 476 { 477 $productkey = $productkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'}; 478 $realproductkey = $realproductkey . " " . $allvariableshashref->{'POSTVERSIONEXTENSION'}; 479 } 480 if ( $allvariableshashref->{'NOVERSIONINDIRNAME'} ) 481 { 482 $productkey = $productname; 483 $realproductkey = $realproductname; 484 } 485 if ( $allvariableshashref->{'NOSPACEINDIRECTORYNAME'} ) 486 { 487 $productkey =~ s/\ /\_/g; 488 $realproductkey =~ s/\ /\_/g; 489 } 490 491 my $shortproductkey = installer::windows::idtglobal::make_eight_three_conform($productkey, "dir"); # third parameter not used 492 $shortproductkey =~ s/\s/\_/g; # changing empty space to underline 493 494 $oneline = "$installer::globals::officemenufolder\t$installer::globals::programmenufolder\t$shortproductkey|$realproductkey\n"; 495 push(@{$directorytableref}, $oneline); 496 } 497 498 $oneline = "TARGETDIR\t\tSourceDir\n"; 499 push(@{$directorytableref}, $oneline); 500 501 $oneline = "$installer::globals::programfilesfolder\tTARGETDIR\t.\n"; 502 push(@{$directorytableref}, $oneline); 503 504 $oneline = "$installer::globals::programmenufolder\tTARGETDIR\t.\n"; 505 push(@{$directorytableref}, $oneline); 506 507 $oneline = "$installer::globals::startupfolder\tTARGETDIR\t.\n"; 508 push(@{$directorytableref}, $oneline); 509 510 $oneline = "$installer::globals::desktopfolder\tTARGETDIR\t.\n"; 511 push(@{$directorytableref}, $oneline); 512 513 $oneline = "$installer::globals::startmenufolder\tTARGETDIR\t.\n"; 514 push(@{$directorytableref}, $oneline); 515 516 $oneline = "$installer::globals::commonfilesfolder\tTARGETDIR\t.\n"; 517 push(@{$directorytableref}, $oneline); 518 519 $oneline = "$installer::globals::commonappdatafolder\tTARGETDIR\t.\n"; 520 push(@{$directorytableref}, $oneline); 521 522 $oneline = "$installer::globals::localappdatafolder\tTARGETDIR\t.\n"; 523 push(@{$directorytableref}, $oneline); 524 525 if ( $installer::globals::usesharepointpath ) 526 { 527 $oneline = "SHAREPOINTPATH\tTARGETDIR\t.\n"; 528 push(@{$directorytableref}, $oneline); 529 } 530 531 $oneline = "$installer::globals::systemfolder\tTARGETDIR\t.\n"; 532 push(@{$directorytableref}, $oneline); 533 534 my $localtemplatefoldername = $installer::globals::templatefoldername; 535 my $directorytableentry = $localtemplatefoldername; 536 my $shorttemplatefoldername = installer::windows::idtglobal::make_eight_three_conform($localtemplatefoldername, "dir"); 537 if ( $shorttemplatefoldername ne $localtemplatefoldername ) { $directorytableentry = "$shorttemplatefoldername|$localtemplatefoldername"; } 538 $oneline = "$installer::globals::templatefolder\tTARGETDIR\t$directorytableentry\n"; 539 push(@{$directorytableref}, $oneline); 540 541 if ( $installer::globals::fontsdirname ) 542 { 543 $oneline = "$installer::globals::fontsfolder\t$installer::globals::fontsdirparent\t$installer::globals::fontsfoldername\:$installer::globals::fontsdirname\n"; 544 } 545 else 546 { 547 $oneline = "$installer::globals::fontsfolder\tTARGETDIR\t$installer::globals::fontsfoldername\n"; 548 } 549 550 push(@{$directorytableref}, $oneline); 551 552} 553 554############################################### 555# Creating the file Director.idt dynamically 556############################################### 557 558sub create_directory_table 559{ 560 my ($directoryref, $basedir, $allvariableshashref, $shortdirnamehashref, $loggingdir) = @_; 561 562 # Structure of the directory table: 563 # Directory Directory_Parent DefaultDir 564 # Directory is a unique identifier 565 # Directory_Parent is the unique identifier of the parent 566 # DefaultDir is .:APPLIC~1|Application Data with 567 # Before ":" : [sourcedir]:[destdir] (not programmed yet) 568 # After ":" : 8+3 and not 8+3 the destination directory name 569 570 installer::logger::include_timestamp_into_logfile("Performance Info: Directory Table start"); 571 572 my @directorytable = (); 573 my $infoline; 574 575 overwrite_programfilesfolder($allvariableshashref); 576 if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_1.log", $directoryref); } 577 create_unique_directorynames($directoryref, $allvariableshashref); 578 if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_1a.log", $directoryref); } 579 create_defaultdir_directorynames($directoryref, $shortdirnamehashref); # only destdir! 580 if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_2.log", $directoryref); } 581 set_installlocation_directory($directoryref, $allvariableshashref); 582 if ( $installer::globals::globallogging ) { installer::files::save_array_of_hashes($loggingdir . "directoriesforidt_local_3.log", $directoryref); } 583 installer::windows::idtglobal::write_idt_header(\@directorytable, "directory"); 584 add_root_directories(\@directorytable, $allvariableshashref); 585 create_directorytable_from_collection(\@directorytable, $directoryref); 586 587 # Saving the file 588 589 my $directorytablename = $basedir . $installer::globals::separator . "Director.idt"; 590 installer::files::save_file($directorytablename ,\@directorytable); 591 $infoline = "Created idt file: $directorytablename\n"; 592 push(@installer::globals::logfileinfo, $infoline); 593 594 installer::logger::include_timestamp_into_logfile("Performance Info: Directory Table end"); 595 596} 597 5981; 599