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