Commits

Anonymous committed b6bb6f8

CWS-TOOLING: integrate CWS native240
2009-05-07 14:15:40 +0200 is r271664 : #i100983# signing process also cygwin ready
2009-05-07 11:54:19 +0200 is r271650 : #i100983# signing process also cygwin ready
2009-05-06 17:37:11 +0200 is r271606 : #i100983# signing process also cygwin ready
2009-05-05 18:28:49 +0200 is r271549 : #i100983# signing process also cygwin ready
2009-04-09 15:51:50 +0200 is r270712 : #i100983# cygwin improvements
2009-04-09 13:57:01 +0200 is r270706 : #i100983# improve cygwin support
2009-04-09 13:56:09 +0200 is r270705 : #i100983# improve cygwin support
2009-04-09 13:55:11 +0200 is r270704 : #i100983# improve cygwin support
2009-04-09 13:54:46 +0200 is r270703 : #i100983# improve cygwin support
2009-04-09 13:54:19 +0200 is r270702 : #i100983# improve cygwin support
2009-04-09 13:53:55 +0200 is r270701 : #i100983# improve cygwin support
2009-04-09 13:53:24 +0200 is r270700 : #i100983# improve cygwin support
2009-04-09 13:52:44 +0200 is r270699 : #i100983# improve cygwin support
2009-04-09 13:51:59 +0200 is r270698 : #i100983# improve cygwin support
2009-04-09 13:51:31 +0200 is r270697 : #i100983# improve cygwin support
2009-04-09 13:48:29 +0200 is r270696 : #i100983# improve cygwin support
2009-04-09 13:47:19 +0200 is r270695 : #i100983# improve cygwin support
2009-04-09 13:47:04 +0200 is r270694 : #i100983# improve cygwin support
2009-04-09 13:45:55 +0200 is r270693 : #i100983# improve cygwin support
2009-04-09 13:45:40 +0200 is r270692 : #i100983# improve cygwin support
2009-04-09 13:44:57 +0200 is r270691 : #i100983# improve cygwin support
2009-04-09 13:44:09 +0200 is r270690 : #i100983# improve cygwin support

Comments (0)

Files changed (20)

setup_native/scripts/admin.pl

 #
 #*************************************************************************
 
+use Cwd;
 use File::Copy;
 
 #################################################################################
 	$globaltempdirname = "ooopackaging";
 	$savetemppath = "";
 	$msiinfo_available = 0;
+	$path_displayed = 0;
 
 	$plat = $^O;
 
 {
 	my ($cabfilename, $unpackdir) = @_;
 	
-	my $expandfile = "expand.exe";	# Has to be in the path
+	my $expandfile = "expand.exe"; # has to be in the PATH
+	
+	# expand.exe has to be located in the system directory.
+	# Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course. 
+	# But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack 
+	# cabinet files.
+
+	if ( $^O =~ /cygwin/i )
+	{
+		$expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory
+		$expandfile =~ s/\\/\//;
+		if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); }
+	}
+	
 	my $expandlogfile = $unpackdir . $separator . "expand.log";
 
 	# exclude cabinet file
 	if ( $^O =~ /cygwin/i ) {
 		my $localunpackdir = qx{cygpath -w "$unpackdir"};
 		$localunpackdir =~ s/\\/\\\\/g;
-		$systemcall = $expandfile . " " . $cabfilename . " -F:\\\* " . $localunpackdir;
+
+		my $localcabfilename = qx{cygpath -w "$cabfilename"};
+		$localcabfilename =~ s/\\/\\\\/g;
+		$localcabfilename =~ s/\s*$//g;
+
+		$systemcall = $expandfile . " " . $localcabfilename . " -F:\* " . $localunpackdir . " \>\/dev\/null 2\>\&1";
 	}
 	else
 	{
 	my $systemcall = "";
 	my $returnvalue = "";
 
+	if ( $^O =~ /cygwin/i ) {
+		chomp( $fullmsidatabasepath = qx{cygpath -w "$fullmsidatabasepath"} ); 
+		# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
+		$fullmsidatabasepath =~ s/\\/\\\\/g;
+		$workdir =~ s/\\/\\\\/g;
+		# and if there are still slashes, they also need to be double backslash
+		$fullmsidatabasepath =~ s/\//\\\\/g;
+		$workdir =~ s/\//\\\\/g;
+	}
+
 	# Export of all tables by using "*"
 							
 	$systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist";
 	return \%fullpathhash;
 }
 
+####################################################################################
+# Cygwin: Setting privileges for files
+####################################################################################
+
+sub change_privileges
+{
+	my ($destfile, $privileges) = @_;
+	
+	my $localcall = "chmod $privileges " . "\"" . $destfile . "\"";
+	system($localcall);
+}
+
+####################################################################################
+# Cygwin: Setting privileges for files recursively
+####################################################################################
+
+sub change_privileges_full
+{
+	my ($target) = @_;
+
+	print "Changing privileges\n";
+
+	my $localcall = "chmod -R 755 " . "\"" . $target . "\"";
+	system($localcall);
+}
+
 ######################################################
 # Creating a new directory with defined privileges
 ######################################################
 			if ( $destfile =~ /\.oxt\s*$/ ) { push(@extensions, $destfile); }
 			# Searching unopkg.exe
 			if ( $destfile =~ /unopkg\.exe\s*$/ ) { $unopkgfile = $destfile; }
+			# if (( $^O =~ /cygwin/i ) && ( $destfile =~ /\.exe\s*$/ )) { change_privileges($destfile, "775"); }
 		}
 		# else	# allowing missing sequence numbers ?
 		# {
 			$temppath =~ s/\\/\\\\/g;
 			chomp( $temppath = qx{cygpath -w "$temppath"} ); 
 		}
-		
+
 		$savetemppath = $temppath;
 	}
 	else
 {
 	my ($unopkgfile, $extension, $temppath) = @_;
 
-	print "... $extension\n";
+	my $from = cwd();
+	
+	my $path = $unopkgfile;
+	get_path_from_fullqualifiedname(\$path);
+	$path =~ s/\\\s*$//;
+	$path =~ s/\/\s*$//;
+
+	my $executable = $unopkgfile;
+	make_absolute_filename_to_relative_filename(\$executable);
+
+	chdir($path);		
+
+	if ( ! $path_displayed )
+	{
+		print "... current dir: $path ...\n";
+		$path_displayed = 1;
+	}
 
 	$temppath =~ s/\\/\//g;
 	$temppath = "/".$temppath;
 
-	my $systemcall = "\"" . $unopkgfile . "\"" . " add --shared --verbose " . "\"" . $extension . "\"" . " -env:UserInstallation=file://" . "\"" . $temppath . "\"" . " 2\>\&1 |";
+	# Converting path of $extension for cygwin
+
+	my $localextension = $extension;
+	if ( $^O =~ /cygwin/i ) {
+		$localextension = qx{cygpath -w "$extension"};
+		$localextension =~ s/\\/\\\\/g;
+	}
+
+	my $systemcall = $executable . " add --shared --verbose " . "\"" . $localextension . "\"" . " -env:UserInstallation=file://" . $temppath . " 2\>\&1 |";
+
+	print "... $systemcall\n";
 
 	my @unopkgoutput = ();
 
 		for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { print "$unopkgoutput[$j]"; }
 		exit_program("ERROR: $systemcall failed!");
 	}
+	
+	chdir($from);
 }
 
 ####################################################################################
 	{
 		print "Registering extensions:\n"; 
 
-		if (( ! -f $unopkgfile ) || ( $unopkgfile eq "" )) { exit_program("ERROR: Could not find unopkg.exe!"); }
-
-		foreach $extension ( @{$extensions} ) { register_one_extension($unopkgfile, $extension, $temppath); }
-		
-		remove_complete_directory($temppath, 1)
+		if (( ! -f $unopkgfile ) || ( $unopkgfile eq "" ))
+		{
+			print("WARNING: Could not find unopkg.exe (Language Pack?)!\n");
+		}
+		else
+		{
+			foreach $extension ( @{$extensions} ) { register_one_extension($unopkgfile, $extension, $temppath); }
+			remove_complete_directory($temppath, 1)
+		}
 	}
 	else
 	{
 
 sub write_sis_info
 {
-	my ($msidatabase) = @_ ;
+	my ($msidatabase) = @_;
 
 	print "Setting SIS in msi database\n";
 	
 	my $wordcount = 4;  # Unpacked files
 	my $lastprinted = get_sis_time_string();
 	my $lastsavedby = "Installer";
-							
-	$systemcall = $msiinfo . " " . "\"" . $msidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
+	
+	my $localmsidatabase = $msidatabase;
+	
+	if( $^O =~ /cygwin/i )
+	{
+		$localmsidatabase = qx{cygpath -w "$localmsidatabase"};
+		$localmsidatabase =~ s/\\/\\\\/g;
+		$localmsidatabase =~ s/\s*$//g;
+	}
+						
+	$systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
+
 	$returnvalue = system($systemcall);
 
 	if ($returnvalue)
 	
 # Unpack all cab files into $helperdir, cab files must be located next to msi database
 my $installdir = $databasepath;
+
 get_path_from_fullqualifiedname(\$installdir);
+
 my $databasefilename = $databasepath;
 make_absolute_filename_to_relative_filename(\$databasefilename);
 
 
 # Copying files
 my ($unopkgfile, $extensions) = copy_files_into_directory_structure($fileorder, $filehash, $componenthash, $fullpathhash, $maxsequence, $unpackdir, $installdir, $dirhash);
+if ( $^O =~ /cygwin/i ) { change_privileges_full($targetdir); }
 	
 my $msidatabase = $targetdir . $separator . $databasefilename;
 my $copyreturn = copy($databasepath, $msidatabase);

solenv/bin/make_download.pl

 installer::downloadsigner::getparameter();
 installer::downloadsigner::checkparameter();
 
+my $temppath = installer::downloadsigner::set_temp_path();
 my $infofilelist = installer::downloadsigner::createproductlist();
 installer::downloadsigner::publishproductlist($infofilelist);
 
 	my $success = 1;
 	my $do_copy = 1;
 	my $followmeinfohash = installer::followme::read_followme_info($infofilename);
-	installer::downloadsigner::setlogfilename();
+	installer::downloadsigner::setlogfilename();	# Successful after reading followme file, resetting log file
+	if ( $installer::globals::writetotemp ) { installer::downloadsigner::set_output_pathes_to_temp($followmeinfohash, $temppath); } 
+	if ( $installer::globals::useminor ) { installer::downloadsigner::set_minor_into_pathes($followmeinfohash, $temppath); } 
 
 	if (( ! $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign ))
 	{
 		installer::logger::print_message( "... WARNING: Signing only for Windows platforms active ...\n" );
 	}
 
-	installer::logger::include_header_into_logfile("Reading include pathes");
-	installer::worker::collect_all_files_from_includepathes($followmeinfohash->{'includepatharray'});
+	# installer::logger::include_header_into_logfile("Reading include pathes");
+	# installer::worker::collect_all_files_from_includepathes($followmeinfohash->{'includepatharray'});
 
 	if (( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign ))
 	{
-		$followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy);
+		$followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy, $temppath);
 
 		($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'},
 																											$followmeinfohash->{'finalinstalldir'},
 		if ( ! $success ) { installer::exiter::exit_program("ERROR: Signing installation set failed: $followmeinfohash->{'finalinstalldir'}", "Main"); }
 	}
 
-	$followmeinfohash->{'finalinstalldir'} = installer::download::create_download_sets($followmeinfohash->{'finalinstalldir'}, 
-																						$followmeinfohash->{'includepatharray'},
-																						$followmeinfohash->{'allvariableshash'},
-																						$followmeinfohash->{'downloadname'},
-																						\$followmeinfohash->{'languagestring'},
-																						$followmeinfohash->{'languagesarray'});
+	if ( ! $installer::globals::nodownload )
+	{
+		$followmeinfohash->{'finalinstalldir'} = installer::download::create_download_sets($followmeinfohash->{'finalinstalldir'}, 
+																							$followmeinfohash->{'includepatharray'},
+																							$followmeinfohash->{'allvariableshash'},
+																							$followmeinfohash->{'downloadname'},
+																							\$followmeinfohash->{'languagestring'},
+																							$followmeinfohash->{'languagesarray'});
 
-	($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'},
-																									$followmeinfohash->{'finalinstalldir'},
-																									$followmeinfohash->{'installlogdir'},
-																									"",
-																									\$followmeinfohash->{'languagestring'},
-																									$followmeinfohash->{'currentinstallnumber'});
+		($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'},
+																										$followmeinfohash->{'finalinstalldir'},
+																										$followmeinfohash->{'installlogdir'},
+																										"",
+																										\$followmeinfohash->{'languagestring'},
+																										$followmeinfohash->{'currentinstallnumber'});
 
-	if (( $success ) && ( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign ))
+		if (( $success ) && ( $installer::globals::iswindowsbuild ) && ( $installer::globals::dosign ))
+		{
+			$do_copy = 0;
+			$followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy, $temppath);
+
+			($success, $followmeinfohash->{'finalinstalldir'}) = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'},
+																											$followmeinfohash->{'finalinstalldir'},
+																											$followmeinfohash->{'installlogdir'},
+																											"",
+																											\$followmeinfohash->{'languagestring'},
+																											$followmeinfohash->{'currentinstallnumber'});
+		}
+	}
+	
+	if ( $success )
 	{
-		$do_copy = 0;
-		$followmeinfohash->{'finalinstalldir'} = installer::windows::sign::sign_install_set($followmeinfohash, $do_copy);
-
-		$followmeinfohash->{'finalinstalldir'} = installer::worker::analyze_and_save_logfile($followmeinfohash->{'loggingdir'},
-																								$followmeinfohash->{'finalinstalldir'},
-																								$followmeinfohash->{'installlogdir'},
-																								"",
-																								\$followmeinfohash->{'languagestring'},
-																								$followmeinfohash->{'currentinstallnumber'});
+		installer::worker::clean_output_tree();
+		if ( $installer::globals::followme_from_directory ) { installer::downloadsigner::rename_followme_infofile($infofilename); }
 	}
 
 	installer::logger::stoptime();
 }
 
-
 ####################################
 # Main program end
 ####################################

solenv/bin/make_installer.pl

 		# Creating Windows msp patches
 		#######################################################
 		
-		if (( $is_success ) && ( $installer::globals::updatedatabase ) && ( $allvariableshashref->{'CREATE_MSP_INSTALLSET'} ) && ( ! ( $^O =~ /cygwin/i )))	# not supported for cygwin yet
+		if (( $is_success ) && ( $installer::globals::updatedatabase ) && ( $allvariableshashref->{'CREATE_MSP_INSTALLSET'} ))
 		{
 			# Required:
 			# Temp path for administrative installations: $installer::globals::temppath

solenv/bin/modules/installer/archivefiles.pm

 
 package installer::archivefiles;
 
+use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
 use installer::converter;
 use installer::existence;
 use installer::exiter;
 
 			if ( $installer::globals::dounzip ) { installer::systemactions::create_directory($unzipdir); }	# creating subdirectories with the names of the zipfiles
 
-			$systemcall = "$installer::globals::unzippath -l $sourcepath |";
-			open (UNZIP, "$systemcall");
-			my @zipfile = <UNZIP>;
-			close (UNZIP);
+			my $zip = Archive::Zip->new();
+			if ( $zip->read($sourcepath) != AZ_OK )
+			{
+				$infoline = "ERROR: Could not unzip $sourcepath\n";
+				push( @installer::globals::logfileinfo, $infoline);				
+			}
 
-			$infoline = "Systemcall: $systemcall\n";
-			push( @installer::globals::logfileinfo, $infoline);
+			my $counter = 0;
+			my $contains_dll = 0;
+			foreach my $member ( $zip->memberNames() )
+			{
+				$counter++;
+				if ( $member =~ /.dll\s*$/ ) { $contains_dll = 1; }
+			}
 
-			if (!( $#zipfile > -1 ))	# the zipfile is empty
+			if (! ( $counter > 0 ))	# the zipfile is empty
 			{
 				$infoline = "ERROR: Could not unzip $sourcepath\n";
 				push( @installer::globals::logfileinfo, $infoline);
 			}
 			else
 			{
-				# now really unpacking the files
-				# Parameter -o : overwrite files without prompting
-				# Parameter -q : quiet mode
-
 				if ( $installer::globals::dounzip )			# really unpacking the files 
 				{					
-					$returnvalue = 1;
-					$systemcall = "$installer::globals::unzippath -o -q $sourcepath -d $unzipdir";
-					$returnvalue = system($systemcall);
+					if ( $zip->extractTree("", $unzipdir) != AZ_OK ) { installer::exiter::exit_program("ERROR: $infoline", "resolving_archive_flag"); }
 
-					$infoline = "Systemcall: $systemcall\n";
-					push( @installer::globals::logfileinfo, $infoline);
-			
-					if ($returnvalue) { installer::exiter::exit_program("ERROR: $infoline", "resolving_archive_flag"); }
-
-					if ( $^O =~ /cygwin/i )
+					if (( $^O =~ /cygwin/i ) && ( $contains_dll ))
 					{
 						# Make dll's executable
 						$systemcall = "cd $unzipdir; find . -name \\*.dll -exec chmod 775 \{\} \\\;";
 				my $zipfileref = \@zipfile;
 				my $unziperror = 0;
 				
-				# Format: Length, Date, Time, Name
-				# This includes new destination directories!				
-				
-				for ( my $j = 0; $j <= $#{$zipfileref}; $j++ )
+				foreach my $zipname ( $zip->memberNames() )
 				{
-					my $line = ${$zipfileref}[$j]; 
-					
-					# Format: 
-					#    0 07-25-03  18:21   dir1/
-					# 1241 07-25-03  18:21   dir1/so7drawing.desktop
+					# Format from Archive:::Zip : 
+					# dir1/
+					# dir1/so7drawing.desktop
 
-					if ( $line =~ /^\s*(\d+)\s+(\S+)\s+(\S+)\s+(\S+.*\S+?)\s*$/ )
+					# some directories and files (from the help) start with "./simpress.idx"
+						
+					$zipname =~ s/^\s*\.\///;
+						
+					if ($installer::globals::iswin and $^O =~ /MSWin/i) { $zipname =~ s/\//\\/g; }
+
+					if ( $zipname =~ /\Q$installer::globals::separator\E\s*$/ )	# slash or backslash at the end characterizes a directory
 					{
-						my $zipsize = $1;
-						my $zipdate = $2;
-						my $ziptime = $3;
-						my $zipname = $4;
+						$zipname = $zipname . "\n";
+						push(@{$additionalpathsref}, $zipname);
+								
+						# Also needed here:
+						# Name
+						# Language
+						# ismultilingual
+						# Basedirectory
+							
+						# This is not needed, because the list of all directories for the 
+						# epm list file is generated from the destination directories of the
+						# files included in the product!	
+					}
+					else
+					{
+						my %newfile = ();
+						%newfile = %{$onefile};
+						$newfile{'Name'} = $zipname;
+						my $destination = $onefile->{'destination'};
+						installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
+						$newfile{'destination'} = $destination . $zipname;
+						$newfile{'sourcepath'} = $unzipdir . $zipname;
+						$newfile{'zipfilename'} = $onefile->{'Name'};
+						$newfile{'zipfilesource'} = $onefile->{'sourcepath'};
+						$newfile{'zipfiledestination'} = $onefile->{'destination'};
 
-						# some directories and files (from the help) start with "./simpress.idx"
+						if (( $use_internal_rights ) && ( ! $installer::globals::iswin ))
+						{
+							my $value = sprintf("%o", (stat($newfile{'sourcepath'}))[2]);
+							$newfile{'UnixRights'} = substr($value, 3);
+							$infoline = "Setting unix rights for \"$newfile{'sourcepath'}\" to \"$newfile{'UnixRights'}\"\n";
+							push( @installer::globals::logfileinfo, $infoline);		
+						}
 						
-						$zipname =~ s/^\s*\.\///;
+						if ( $select_files )
+						{
+							if ( ! installer::existence::exists_in_array($zipname,$selectlistfiles) )
+							{
+								$infoline = "Removing from ARCHIVE file $onefilename: $zipname\n";
+								push( @installer::globals::logfileinfo, $infoline);		
+								next; # ignoring files, that are not included in $selectlistfiles
+							}
+							else
+							{
+								$infoline = "Keeping from ARCHIVE file $onefilename: $zipname\n";
+								push( @installer::globals::logfileinfo, $infoline);		
+								push( @keptfiles, $zipname); # collecting all kept files
+							}			
+						}
 						
-						if ($installer::globals::iswin and $^O =~ /MSWin/i) { $zipname =~ s/\//\\/g; }
+						if ( $select_patch_files )
+						{
+							# Is this file listed in the Patchfile list?
+							# $zipname (filename including path in zip file has to be listed in patchfile list
+							
+							if ( ! installer::existence::exists_in_array($zipname,$patchlistfiles) )
+							{
+								$newfile{'Styles'} =~ s/\bPATCH\b//;	# removing the flag PATCH
+								$newfile{'Styles'} =~ s/\,\s*\,/\,/;
+								$newfile{'Styles'} =~ s/\(\s*\,/\(/;
+								$newfile{'Styles'} =~ s/\,\s*\)/\)/;
+								# $infoline = "Removing PATCH flag from: $zipname\n";
+								# push( @installer::globals::logfileinfo, $infoline);	
+							}
+							else
+							{
+								# $infoline = "Keeping PATCH flag at: $zipname\n";
+								# push( @installer::globals::logfileinfo, $infoline);		
+								push( @keptpatchflags, $zipname); # collecting all PATCH flags 
+							}
+						}
+							
+						if ( $rename_to_language )
+						{
+							my $newzipname = put_language_into_name($zipname, $onelanguage);
+							my $oldfilename = $unzipdir . $zipname;
+							my $newfilename = $unzipdir . $newzipname;
 
-						# if ( $zipsize == 0 )	# also files can have a size of 0
-						if ( $zipname =~ /\Q$installer::globals::separator\E\s*$/ )	# slash or backslash at the end characterizes a directory
+							installer::systemactions::copy_one_file($oldfilename, $newfilename);
+
+							$newfile{'Name'} = $newzipname;
+							$newfile{'destination'} = $destination . $newzipname;
+							$newfile{'sourcepath'} = $unzipdir . $newzipname;
+
+							$infoline = "RENAME_TO_LANGUAGE: Using $newzipname instead of $zipname!\n";
+							push( @installer::globals::logfileinfo, $infoline);
+						}
+							
+						my $sourcefiletest = $unzipdir . $zipname;							
+						if ( ! -f $sourcefiletest )
 						{
-							$zipname = $zipname . "\n";
-							push(@{$additionalpathsref}, $zipname);
-								
-							# Also needed here:
-							# Name
-							# Language
-							# ismultilingual
-							# Basedirectory
-							
-							# This is not needed, because the list of all directories for the 
-							# epm list file is generated from the destination directories of the
-							# files included in the product!	
+							$infoline = "ATTENTION: Unzip failed for $sourcefiletest!\n";
+							push( @installer::globals::logfileinfo, $infoline);
+							$unziperror = 1;
 						}
-						else
-						{
-							my %newfile = ();
-							%newfile = %{$onefile};
-							$newfile{'Name'} = $zipname;
-							my $destination = $onefile->{'destination'};
-							installer::pathanalyzer::get_path_from_fullqualifiedname(\$destination);
-							$newfile{'destination'} = $destination . $zipname;
-							$newfile{'sourcepath'} = $unzipdir . $zipname;
-							$newfile{'zipfilename'} = $onefile->{'Name'};
-							$newfile{'zipfilesource'} = $onefile->{'sourcepath'};
-							$newfile{'zipfiledestination'} = $onefile->{'destination'};
 
-							if (( $use_internal_rights ) && ( ! $installer::globals::iswin ))
-							{
-								my $value = sprintf("%o", (stat($newfile{'sourcepath'}))[2]);
-								$newfile{'UnixRights'} = substr($value, 3);
-								$infoline = "Setting unix rights for \"$newfile{'sourcepath'}\" to \"$newfile{'UnixRights'}\"\n";
-								push( @installer::globals::logfileinfo, $infoline);		
-							}
-							
-							if ( $select_files )
-							{
-								if ( ! installer::existence::exists_in_array($zipname,$selectlistfiles) )
-								{
-									$infoline = "Removing from ARCHIVE file $onefilename: $zipname\n";
-									push( @installer::globals::logfileinfo, $infoline);		
-									next; # ignoring files, that are not included in $selectlistfiles
-								}
-								else
-								{
-									$infoline = "Keeping from ARCHIVE file $onefilename: $zipname\n";
-									push( @installer::globals::logfileinfo, $infoline);		
-									push( @keptfiles, $zipname); # collecting all kept files
-								}			
-							}
-							
-							if ( $select_patch_files )
-							{
-								# Is this file listed in the Patchfile list?
-								# $zipname (filename including path in zip file has to be listed in patchfile list
-								
-								if ( ! installer::existence::exists_in_array($zipname,$patchlistfiles) )
-								{
-									$newfile{'Styles'} =~ s/\bPATCH\b//;	# removing the flag PATCH
-									$newfile{'Styles'} =~ s/\,\s*\,/\,/;
-									$newfile{'Styles'} =~ s/\(\s*\,/\(/;
-									$newfile{'Styles'} =~ s/\,\s*\)/\)/;
-									# $infoline = "Removing PATCH flag from: $zipname\n";
-									# push( @installer::globals::logfileinfo, $infoline);	
-								}
-								else
-								{
-									# $infoline = "Keeping PATCH flag at: $zipname\n";
-									# push( @installer::globals::logfileinfo, $infoline);		
-									push( @keptpatchflags, $zipname); # collecting all PATCH flags 
-								}
-							}
-							
-							if ( $rename_to_language )
-							{
-								my $newzipname = put_language_into_name($zipname, $onelanguage);
-								my $oldfilename = $unzipdir . $zipname;
-								my $newfilename = $unzipdir . $newzipname;
+						# only adding the new line into the files array, if not in repeat modus
 
-								installer::systemactions::copy_one_file($oldfilename, $newfilename);
-
-								$newfile{'Name'} = $newzipname;
-								$newfile{'destination'} = $destination . $newzipname;
-								$newfile{'sourcepath'} = $unzipdir . $newzipname;
-
-								$infoline = "RENAME_TO_LANGUAGE: Using $newzipname instead of $zipname!\n";
-								push( @installer::globals::logfileinfo, $infoline);
-							}
-							
-							my $sourcefiletest = $unzipdir . $zipname;							
-							if ( ! -f $sourcefiletest )
-							{
-								$infoline = "ATTENTION: Unzip failed for $sourcefiletest!\n";
-								push( @installer::globals::logfileinfo, $infoline);
-								$unziperror = 1;
-							}
-
-							# only adding the new line into the files array, if not in repeat modus
-
-							if ( ! $repeat_unzip ) { push(@newallfilesarray, \%newfile); }			
-						}		
-					}										
+						if ( ! $repeat_unzip ) { push(@newallfilesarray, \%newfile); }			
+					}		
 				}
 
 				# Comparing the content of @keptfiles and $selectlistfiles

solenv/bin/modules/installer/control.pm

 sub check_system_path
 {
 	# The following files have to be found in the environment variable PATH
-	# All platforms: zip, unzip
+	# All platforms: zip
 	# Windows only: msvcp70.dll, msvcr70.dll for regcomp.exe
 	# Windows only: "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe" for msi database and packaging
 
 
 	if (($installer::globals::iswin) && ($installer::globals::iswindowsbuild))
 	{
-		@needed_files_in_path = ("zip.exe", "unzip.exe", "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe");
+		@needed_files_in_path = ("zip.exe", "msiinfo.exe", "msidb.exe", "uuidgen.exe", "makecab.exe", "msitran.exe", "expand.exe");
 		
 		if ( $installer::globals::compiler eq "wntmsci8" )
 		{
 	}
 	elsif ($installer::globals::iswin)
 	{	
-		@needed_files_in_path = ("zip.exe", "unzip.exe");
+		@needed_files_in_path = ("zip.exe");
 	}
 	else
 	{
-		@needed_files_in_path = ("zip", "unzip");
+		@needed_files_in_path = ("zip");
 	}
 
 	foreach $onefile ( @needed_files_in_path )

solenv/bin/modules/installer/download.pm

 	my ($includepatharrayref) = @_;
 	
 	my $getuidlibraryname = "getuid.so";
-	my $getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0);
+
+	my $getuidlibraryref = "";
+
+	if ( $installer::globals::include_pathes_read )
+	{
+		$getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$getuidlibraryname, $includepatharrayref, 0);
+	}
+	else
+	{
+		$getuidlibraryref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$getuidlibraryname, $includepatharrayref, 0);
+	}
+
 	if ($$getuidlibraryref eq "") { installer::exiter::exit_program("ERROR: Could not find $getuidlibraryname!", "get_path_for_library"); }
 	
 	return $$getuidlibraryref;
 	if ( ! $allvariables->{'DOWNLOADBANNER'} ) { installer::exiter::exit_program("ERROR: DOWNLOADBANNER not defined in product definition!", "put_banner_bmp_into_template"); }
 	my $filename = $allvariables->{'DOWNLOADBANNER'};
 
-	my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);
+	my $completefilenameref = "";
+
+	if ( $installer::globals::include_pathes_read )
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);		
+	}
+	else
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0);
+	}
+
+	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_banner_bmp_into_template"); }
 
 	if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; }
 
-	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_banner_bmp_into_template"); }
-
 	replace_one_variable($templatefile, "BANNERBMPPLACEHOLDER", $$completefilenameref);
 }
 
 	if ( ! $allvariables->{'DOWNLOADBITMAP'} ) { installer::exiter::exit_program("ERROR: DOWNLOADBITMAP not defined in product definition!", "put_welcome_bmp_into_template"); }
 	my $filename = $allvariables->{'DOWNLOADBITMAP'};
 
-	my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);
+	my $completefilenameref = "";
+
+	if ( $installer::globals::include_pathes_read )
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);
+	}
+	else
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0);
+	}
+
+	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_welcome_bmp_into_template"); }
 
 	if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; }
 
-	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_welcome_bmp_into_template"); }
-
 	replace_one_variable($templatefile, "WELCOMEBMPPLACEHOLDER", $$completefilenameref);
 }
 
 	if ( ! $allvariables->{'DOWNLOADSETUPICO'} ) { installer::exiter::exit_program("ERROR: DOWNLOADSETUPICO not defined in product definition!", "put_setup_ico_into_template"); }
 	my $filename = $allvariables->{'DOWNLOADSETUPICO'};
 
-	my $completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);
+	my $completefilenameref = "";
+
+	if ( $installer::globals::include_pathes_read )
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$filename, $includepatharrayref, 0);
+	}
+	else
+	{
+		$completefilenameref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$filename, $includepatharrayref, 0);
+	}
+
+	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_setup_ico_into_template"); }
 
 	if ( $^O =~ /cygwin/i ) { $$completefilenameref =~ s/\//\\/g; }
 
-	if ($$completefilenameref eq "") { installer::exiter::exit_program("ERROR: Could not find download file $filename!", "put_setup_ico_into_template"); }
-
 	replace_one_variable($templatefile, "SETUPICOPLACEHOLDER", $$completefilenameref);
 }
 
 			my $onefile = ${$files}[$j];
 		
 			my $fileline = "  " . "File" . " " . "\"" . $onefile . "\"" . "\n";
+
 			if ( $^O =~ /cygwin/i ) {
 				$fileline =~ s/\//\\/g;
 			}
 
 	installer::logger::print_message( "... starting $makensisexe ... \n" );
 
+	if( $^O =~ /cygwin/i ) { $nsifile =~ s/\\/\//g;	}
+
 	my $systemcall = "$makensisexe $nsifile |";
 
 	my $infoline = "Systemcall: $systemcall\n";
 	# removing existing directory "_native_packed_inprogress" and "_native_packed_witherror" and "_native_packed"
 
 	my $downloaddir = $firstdir . $lastdir;
+	
 	if ( -d $downloaddir ) { installer::systemactions::remove_complete_directory($downloaddir); }
 	
 	my $olddir = $downloaddir;
 		{
 			# find and read setup script template
 			my $scriptfilename = "downloadscript.sh";
-			my $scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfilename, $includepatharrayref, 0);
+
+			my $scriptref = "";
+
+			if ( $installer::globals::include_pathes_read )
+			{
+				$scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$scriptfilename, $includepatharrayref, 0);
+			}
+			else
+			{
+				$scriptref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$scriptfilename, $includepatharrayref, 0);
+			}
+
 			if ($$scriptref eq "") { installer::exiter::exit_program("ERROR: Could not find script file $scriptfilename!", "create_download_sets"); }
 			my $scriptfile = installer::files::read_file($$scriptref);
 
 		
 		# find and read the nsi file template
 		my $templatefilename = "downloadtemplate.nsi";
-		my $templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$templatefilename, $includepatharrayref, 0);
+
+		my $templateref = "";
+
+		if ( $installer::globals::include_pathes_read )
+		{
+			$templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath(\$templatefilename, $includepatharrayref, 0);
+		}
+		else
+		{
+			$templateref = installer::scriptitems::get_sourcepath_from_filename_and_includepath_classic(\$templatefilename, $includepatharrayref, 0);
+		}
+
 		if ($$templateref eq "") { installer::exiter::exit_program("ERROR: Could not find nsi template file $templatefilename!", "create_download_sets"); }
 		my $templatefile = installer::files::read_file($$templateref);
 

solenv/bin/modules/installer/downloadsigner.pm

 {
 	print <<Ende;
 --------------------------------------------------------------------------------
-make_download V1.0 (c) Ingo Schmidt-Rosbiegal 2009
+make_download V1.0
 The following parameter are needed:
 -d: Full path to the file containing the follow-me info or to a directory
     containing the follow-me info files. In the latter case, all follow-me
-    info files are evaluated.
+    info files are evaluated. If a directory is used, the successfully used 
+    follow-me info files are renamed using a string "success". Files with
+    this string are ignored in repeated processes using "-d" with a 
+    directory.
+
 The following parameter are optional:
+-nodownload: Only signing, no creation of download sets (Windows only)
+-useminor: Important for installation sets, created without minor set
+-writetotemp: Necessary, if you do not want to write into solver
+              This can be caused by missing privileges (Windows only)
+-internalcabinet: Not only the cabinet files are signed, but also all
+                  files included in the cabinet files (Windows only).
+
 -sign: Uses signing mechanism to sign installation sets
 If \"-sign\" is set, the following two parameter are required:
 -pfx: Full path to the pfx file
 
 Specifying an installation set (with "-d"):
 
-perl make_sign_and_download.pl -d <followmeinfofilename>
-perl make_sign_and_download.pl -d <followmeinfofilename>
-                               -sign
-                               -pfx <pfxfilename>
-                               -pw <passwordfilename> 
+perl make_download.pl -d <followmeinfofilename>
+
+perl make_download.pl -d <followmeinfofilename>
+                         -sign
+                         -pfx <pfxfilename>
+                         -pw <passwordfilename> 
                                
 or without specifying an installation set:
 
-perl make_sign_and_download.pl -sign
-                               -pfx <pfxfilename>
-                               -pw <passwordfilename> 
+perl make_download.pl -d <followmedirectory>
+                      -sign
+                      -pfx <pfxfilename>
+                      -pw <passwordfilename> 
 --------------------------------------------------------------------------------
 Ende
 	exit(-1);
 		elsif ($param eq "-pw") { $installer::globals::pwfile = shift(@ARGV); }
 		elsif ($param eq "-pfx") { $installer::globals::pfxfile = shift(@ARGV); }
 		elsif ($param eq "-sign") { $installer::globals::dosign = 1; }
+		elsif ($param eq "-nodownload") { $installer::globals::nodownload = 1; }
+		elsif ($param eq "-writetotemp") { $installer::globals::writetotemp = 1; }
+		elsif ($param eq "-useminor") { $installer::globals::useminor = 1; }
+		elsif ($param eq "-internalcabinet") { $installer::globals::internal_cabinet_signing = 1; }
 		else
 		{
 			installer::logger::print_error( "unknown parameter: $param" );
 }
 
 #############################################
+# Setting the temporary path for the download 
+# and signing process
+#############################################
+
+sub set_temp_path
+{
+	my $temppath = "";
+	my $pid = $$;			# process id
+	my $time = time();		# time
+	my $helperdir = "unpackdir_" . $pid . $time;
+	
+	if (( $ENV{'TMP'} ) || ( $ENV{'TEMP'} ))
+	{
+		if ( $ENV{'TMP'} ) { $temppath = $ENV{'TMP'}; }
+		elsif ( $ENV{'TEMP'} )  { $temppath = $ENV{'TEMP'}; }
+		$temppath =~ s/\Q$installer::globals::separator\E\s*$//;	# removing ending slashes and backslashes
+		$temppath = $temppath . $installer::globals::separator . $helperdir;
+
+		if( $^O =~ /cygwin/i )
+		{
+			$temppath = qx{cygpath -w "$temppath"};
+			$temppath =~ s/\\/\//g;
+			$temppath =~ s/\s*$//g;
+		}
+
+		installer::systemactions::create_directory_structure($temppath);
+	}
+	else
+	{
+		installer::logger::print_error( "Error: TMP and TEMP not defined. This is required for this process.\n" );
+		usage();
+		exit(-1);
+	}
+	
+	installer::logger::print_message( "\n... using output path: $temppath ...\n" );
+	
+	push(@installer::globals::removedirs, $temppath);
+	
+	return $temppath;
+}
+
+#############################################
+# Setting output pathes to temp directory
+# This are the:
+# unpackpath and the loggingdir
+#############################################
+
+sub set_output_pathes_to_temp
+{
+	my ($followmeinfohash, $temppath) = @_;
+	
+	$followmeinfohash->{'loggingdir'} = $temppath . $installer::globals::separator;
+	$installer::globals::unpackpath = $temppath;
+}
+
+#############################################
+# Setting the minor into the pathes. This is
+# required, if the original installation set
+# was created without minor
+# Value is always saved in 
+# $installer::globals::lastminor
+# which is saved in the follow_me file
+#############################################
+
+sub set_minor_into_pathes
+{
+	my ($followmeinfohash, $temppath) = @_;
+	
+	installer::logger::print_message( "\n... forcing into minor: $installer::globals::lastminor ...\n" );
+	
+	my @pathnames = ("bin", "doc", "inc", "lib", "pck", "res", "xml");
+	my $sourcename = "src";
+	my $srcpath = $installer::globals::separator . $sourcename . $installer::globals::separator;
+	
+	if ( $installer::globals::minor ne "" )
+	{
+		installer::logger::print_message( "\n... already defined minor: $installer::globals::minor -> ignoring parameter \"-useminor\" ...\n" );
+		return;
+	}
+
+	# Affected pathes:
+	# $contenthash{'installlogdir'}
+	# $contenthash{'includepatharray'}
+	# $installer::globals::unpackpath
+	# $installer::globals::idttemplatepath
+	# $installer::globals::idtlanguagepath
+
+	installer::logger::include_header_into_logfile("Changing saved pathes to add the minor");
+	my $infoline = "Old pathes:\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$followmeinfohash->{'installlogdir'}: $followmeinfohash->{'installlogdir'}\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::unpackpath: $installer::globals::unpackpath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::idttemplatepath: $installer::globals::idttemplatepath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::idtlanguagepath: $installer::globals::idtlanguagepath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "Include pathes:\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { push( @installer::globals::logfileinfo, $path); }
+	
+	foreach $onepath ( @pathnames )
+	{
+		my $oldvalue = $installer::globals::separator . $onepath . $installer::globals::separator;
+		my $newvalue = $installer::globals::separator . $onepath . "\." . $installer::globals::lastminor . $installer::globals::separator;
+	
+		if (( $followmeinfohash->{'installlogdir'} =~ /\Q$oldvalue\E/ ) && ( ! ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ))) { $followmeinfohash->{'installlogdir'} =~ s/\Q$oldvalue\E/$newvalue/; }
+		if (( $installer::globals::unpackpath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ))) { $installer::globals::unpackpath =~ s/\Q$oldvalue\E/$newvalue/; }
+		if (( $installer::globals::idttemplatepath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idttemplatepath =~ s/\Q$oldvalue\E/$newvalue/; }
+		if (( $installer::globals::idtlanguagepath =~ /\Q$oldvalue\E/ ) && ( ! ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idtlanguagepath =~ s/\Q$oldvalue\E/$newvalue/; }
+		foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { if (( $path =~ /\Q$oldvalue\E/ ) && ( ! ( $path =~ /\Q$srcpath\E/ ))) { $path =~ s/\Q$oldvalue\E/$newvalue/; } }
+
+		# Checking for the end of the path
+		$oldvalue = $installer::globals::separator . $onepath;
+		$newvalue = $installer::globals::separator . $onepath . "\." . $installer::globals::lastminor;
+
+		if (( $followmeinfohash->{'installlogdir'} =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ))) { $followmeinfohash->{'installlogdir'} =~ s/\Q$oldvalue\E\s*$/$newvalue/; }
+		if (( $installer::globals::unpackpath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ))) { $installer::globals::unpackpath =~ s/\Q$oldvalue\E\s*$/$newvalue/; }
+		if (( $installer::globals::idttemplatepath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idttemplatepath =~ s/\Q$oldvalue\E\s*$/$newvalue/; }
+		if (( $installer::globals::idtlanguagepath =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ))) { $installer::globals::idtlanguagepath =~ s/\Q$oldvalue\E\s*$/$newvalue/; }
+		foreach my $path ( @{$followmeinfohash->{'includepatharray'}} )
+		{
+			if (( $path =~ /\Q$oldvalue\E\s*$/ ) && ( ! ( $path =~ /\Q$srcpath\E/ )))
+			{
+				$path =~ s/\Q$oldvalue\E\s*$/$newvalue/;
+				$path = $path . "\n";
+			}
+		}
+	}
+
+	# And now can follow the replacement for the source path "src". Subdirs like "bin" in the source tree
+	# must not get the minor. This is instead "src.m9/instsetoo_native/common.pro/bin/..."
+	# Directory "src" can never be the end of the path
+
+	my $newsrcpath = $installer::globals::separator . $sourcename . "\." . $installer::globals::lastminor . $installer::globals::separator;
+	
+	if ( $followmeinfohash->{'installlogdir'} =~ /\Q$srcpath\E/ ) { $followmeinfohash->{'installlogdir'} =~ s/\Q$srcpath\E/$newsrcpath/; }
+	if ( $installer::globals::unpackpath =~ /\Q$srcpath\E/ ) { $installer::globals::unpackpath =~ s/\Q$srcpath\E/$newsrcpath/; }
+	if ( $installer::globals::idttemplatepath =~ /\Q$srcpath\E/ ) { $installer::globals::idttemplatepath =~ s/\Q$srcpath\E/$newsrcpath/; }
+	if ( $installer::globals::idtlanguagepath =~ /\Q$srcpath\E/ ) { $installer::globals::idtlanguagepath =~ s/\Q$srcpath\E/$newsrcpath/; }
+	foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { if ( $path =~ /\Q$srcpath\E/ ) { $path =~ s/\Q$srcpath\E/$newsrcpath/; } }
+
+	$infoline = "\nNew pathes:\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$followmeinfohash->{'installlogdir'}: $followmeinfohash->{'installlogdir'}\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::unpackpath: $installer::globals::unpackpath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::idttemplatepath: $installer::globals::idttemplatepath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "\$installer::globals::idtlanguagepath: $installer::globals::idtlanguagepath\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	$infoline = "Include pathes:\n";
+	push( @installer::globals::logfileinfo, $infoline);
+	foreach my $path ( @{$followmeinfohash->{'includepatharray'}} ) { push( @installer::globals::logfileinfo, $path); }
+}
+
+#############################################
 # Setting the name of the log file
 #############################################
 
 	# If "-d" specifies an installation set, there is only one product
 	
 	my @infofilelist = ();
+	my @infofilelist2 = ();
 	
 	if ( -f $installer::globals::followmeinfofilename )
 	{
 		push(@infofilelist, $installer::globals::followmeinfofilename);
+		# Saving info, that this is a file
+		$installer::globals::followme_from_directory = 0;
 	}
 	elsif ( -d $installer::globals::followmeinfofilename )
 	{
 			exit(-1);				
 		}
 
+		# Saving info, that this is a directory
+		$installer::globals::followme_from_directory = 1;
+
 		# Collect all possible installation sets
 		# CWS: All installation sets
 		# Master: All installation sets with same major, minor and buildid. Additionally using the highest number.
 			{
 				my $fullfilename = $installer::globals::followmeinfofilename . $installer::globals::separator . $onefile;
 				my $installdir = get_property_from_file($fullfilename, "finalinstalldir");
-				if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist, $fullfilename); }
+				if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist2, $fullfilename); }
 			}
 		}
 		else
 				my $fullfilename = $installer::globals::followmeinfofilename . $installer::globals::separator . $onefile;
 				# Check, if installation set still exists
 				my $installdir = get_property_from_file($fullfilename, "finalinstalldir");
-				if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist, $fullfilename); }
+				if (( $installdir ne "" ) && ( -d $installdir )) { push(@infofilelist2, $fullfilename); }
 			}
-		}			
+		}	
 		
+		# Removing all files, starting with "follow_me_success_" in their names. This have already been used successfully.
+		
+		foreach my $onefile ( @infofilelist2 )
+		{
+			if ( $onefile =~ /follow_me_success_/ ) { next; }	
+			push(@infofilelist, $onefile);
+		}		
+
 		# Checking, if there is content in the list
 		if ( ! ( $#infofilelist > -1 ))
 		{
 	foreach my $key ( sort keys %{$followmehash->{'allvariableshash'}} ) { print "allvariableshash: $key : $followmehash->{'allvariableshash'}->{$key}\n"; }
 }
 
+########################################################################
+# Renaming the follow me info file, if it was successfully used.
+# This can only be done, if the parameter "-d" was used with a 
+# directory, not a name. In this case the repeated use of parameter
+# "-d" with this directory has to ignore this already successfully 
+# used file. 
+########################################################################
+
+sub rename_followme_infofile
+{
+	my ( $filename ) = @_;
+	
+	my $newfilename = $filename;
+	$newfilename =~ s/follow_me_/follow_me_success_/;	# including "_success" after "follow_me"
+	
+	if ( $filename ne $newfilename )
+	{
+		my $returnvalue = rename($filename, $newfilename);
+		if ( $returnvalue ) { installer::logger::print_message( "\n... renamed file \"$filename\" to \"$newfilename\" ...\n" ); }
+	}
+}
+
 1;

solenv/bin/modules/installer/epmfile.pm

 {
 	my $rpmversion = 0;
 	my $rpmout = "";
+	my $systemcall = "";
 	
-	my $systemcall = "rpm --version |";
+	# my $systemcall = "rpm --version |";
+	# "rpm --version" has problems since LD_LIBRARY_PATH was removed. Therefore the content of $RPM has to be called.
+	# "rpm --version" and "rpmbuild --version" have the same output. Therefore $RPM can be used. Its value 
+	# is saved in $installer::globals::rpm
+	
+	if ( $installer::globals::rpm ne "" )
+	{
+		$systemcall = "$installer::globals::rpm --version |";
+	}
+	else
+	{
+		$systemcall = "rpm --version |";		
+	}
+	
 	open (RPM, "$systemcall");
 	$rpmout = <RPM>;
 	close (RPM);
 	
-	$rpmout =~ s/\s*$//g;
-
-	my $infoline = "Systemcall: $systemcall\n";
-	push( @installer::globals::logfileinfo, $infoline);
-
-	if ( $rpmout eq "" ) { $infoline = "ERROR: Could not find file \"rpm\" !\n"; }
-	else { $infoline = "Success: rpm version: $rpmout\n"; }
-
-	push( @installer::globals::logfileinfo, $infoline);
+	if ( $rpmout ne "" )
+	{
+		$rpmout =~ s/\s*$//g;
+
+		my $infoline = "Systemcall: $systemcall\n";
+		push( @installer::globals::logfileinfo, $infoline);
+
+		if ( $rpmout eq "" ) { $infoline = "ERROR: Could not find file \"rpm\" !\n"; }
+		else { $infoline = "Success: rpm version: $rpmout\n"; }
+
+		push( @installer::globals::logfileinfo, $infoline);
 	
-	if ( $rpmout =~ /(\d+)\.(\d+)\.(\d+)/ ) { $rpmversion = $1; }
-	elsif ( $rpmout =~ /(\d+)\.(\d+)/ ) { $rpmversion = $1; }
-	elsif ( $rpmout =~ /(\d+)/ ) { $rpmversion = $1; }
-	else { installer::exiter::exit_program("ERROR: Unknown format: $rpmout ! Expected: \"a.b.c\", or \"a.b\", or \"a\"", "determine_rpm_version"); }
+		if ( $rpmout =~ /(\d+)\.(\d+)\.(\d+)/ ) { $rpmversion = $1; }
+		elsif ( $rpmout =~ /(\d+)\.(\d+)/ ) { $rpmversion = $1; }
+		elsif ( $rpmout =~ /(\d+)/ ) { $rpmversion = $1; }
+		else { installer::exiter::exit_program("ERROR: Unknown format: $rpmout ! Expected: \"a.b.c\", or \"a.b\", or \"a\"", "determine_rpm_version"); }
+	}
 	
 	return $rpmversion;
 }
 		installer::logger::print_message( "... $systemcall ...\n" );
 
 		my $maxrpmcalls = 3;
+		my $rpm_failed = 0;
 
 		for ( my $i = 1; $i <= $maxrpmcalls; $i++ )
 		{
 
 			for ( my $j = 0; $j <= $#rpmoutput; $j++ )
 			{
-				if ( $i < $maxrpmcalls ) { $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; }
+				# if ( $i < $maxrpmcalls ) { $rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig; }
+				$rpmoutput[$j] =~ s/\bERROR\b/PROBLEM/ig;
 				push( @installer::globals::logfileinfo, "$rpmoutput[$j]");
 			}
 			
 			{
 				$infoline = "Try $i : Could not execute \"$systemcall\"!\n";
 				push( @installer::globals::logfileinfo, $infoline);
-				if ( $i == $maxrpmcalls ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "create_packages_without_epm"); }
+				$rpm_failed = 1;
 			}
 			else
 			{
 				installer::logger::print_message( "Success (Try $i): \"$systemcall\"\n" );
 				$infoline = "Success: Executed \"$systemcall\" successfully!\n";
 				push( @installer::globals::logfileinfo, $infoline);
+				$rpm_failed = 0;
 				last;
 			}
 		}
-	}	
+		
+		if ( $rpm_failed )
+		{
+			# Because of the problems with LD_LIBARY_PATH, a direct call of local "rpm" or "rpmbuild" might be successful
+			my $rpmprog = "";
+			if ( -f "/usr/bin/rpmbuild" ) { $rpmprog = "/usr/bin/rpmbuild"; }
+			elsif ( -f "/usr/bin/rpm" ) { $rpmprog = "/usr/bin/rpm"; }
+			
+			if ( $rpmprog ne "" )
+			{
+				installer::logger::print_message( "... $rpmprog ...\n" );
+
+				my $helpersystemcall = "$rpmprog -bb $specfilename --target $target $buildrootstring 2\>\&1 |";
+
+				my @helperrpmoutput = ();
+
+				open (RPM, "$helpersystemcall");
+				while (<RPM>) {push(@helperrpmoutput, $_); }
+				close (RPM);
+
+				my $helperreturnvalue = $?;	# $? contains the return value of the systemcall
+
+				$infoline = "\nLast try: Using $rpmprog directly (problem with LD_LIBARY_PATH)\n";
+				push( @installer::globals::logfileinfo, $infoline);
+
+				$infoline = "\nSystemcall: $helpersystemcall\n";
+				push( @installer::globals::logfileinfo, $infoline);
+
+				for ( my $j = 0; $j <= $#helperrpmoutput; $j++ ) { push( @installer::globals::logfileinfo, "$helperrpmoutput[$j]"); }
+			
+				if ($helperreturnvalue)
+				{
+					$infoline = "Could not execute \"$helpersystemcall\"!\n";
+					push( @installer::globals::logfileinfo, $infoline);
+				}
+				else
+				{
+					installer::logger::print_message( "Success: \"$helpersystemcall\"\n" );
+					$infoline = "Success: Executed \"$helpersystemcall\" successfully!\n";
+					push( @installer::globals::logfileinfo, $infoline);
+					$rpm_failed = 0;
+				}
+			}
+			
+			# Now it is really time to exit this packaging process, if the error still occurs
+			if ( $rpm_failed ) { installer::exiter::exit_program("ERROR: \"$systemcall\"!", "create_packages_without_epm"); }
+		}
+	}
 }
 
 #################################################

solenv/bin/modules/installer/followme.pm

 		my $line = ${$filecontent}[$i];
 
 		if ( $line =~ /^\s*finalinstalldir:\s*(.*?)\s*$/ ) { $finalinstalldir = $1; }
+		if( $^O =~ /cygwin/i ) { $finalinstalldir =~ s/\\/\//; }
+		if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $finalinstalldir =~ s/\//\\/; }
 		if ( $line =~ /^\s*downloadname:\s*(.*?)\s*$/ ) { $downloadname = $1; }
 		if ( $line =~ /^\s*currentinstallnumber:\s*(.*?)\s*$/ ) { $currentinstallnumber = $1; }
 		if ( $line =~ /^\s*loggingdir:\s*(.*?)\s*$/ ) { $loggingdir = $1; }
+		if( $^O =~ /cygwin/i ) { $loggingdir =~ s/\\/\//; }
+		if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $loggingdir =~ s/\//\\/; }
 		if ( $line =~ /^\s*installlogdir:\s*(.*?)\s*$/ ) { $installlogdir = $1; }
+		if( $^O =~ /cygwin/i ) { $installlogdir =~ s/\\/\//; }
+		if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installlogdir =~ s/\//\\/; }
 		if ( $line =~ /^\s*languagestring:\s*(.*?)\s*$/ ) { $languagestring = $1; }
 		if ( $line =~ /^\s*languagesarray:\s*(.*?)\s*$/ ) { push(@languagesarray, $1); }
-		if ( $line =~ /^\s*includepatharray:\s*(.*?)\s*$/ ) { push(@includepatharray, $1 . "\n"); }
+		if ( $line =~ /^\s*includepatharray:\s*(.*?)\s*$/ )
+		{
+			my $path = $1;
+			if( $^O =~ /cygwin/i ) { $path  =~ s/\\/\//; }
+			if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $path =~ s/\//\\/; }
+			push(@includepatharray, $path . "\n");
+		}
 		if ( $line =~ /^\s*allvariableshash:\s*(.*?)\s*:\s*(.*?)\s*$/ ) { $allvariableshash{$1} = $2; }
 		if ( $line =~ /^\s*globals:(.*?)\s*:\s*(.*?)\s*$/ )
 		{
 			if ( $name eq "issolaris" ) { $installer::globals::issolaris = $value; }
 			if ( $name eq "islinux" ) { $installer::globals::islinux = $value; }
 			if ( $name eq "unpackpath" ) { $installer::globals::unpackpath = $value; }
+			if( $^O =~ /cygwin/i ) { $installer::globals::unpackpath =~ s/\\/\//; }
+			if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::unpackpath =~ s/\//\\/; }
 			if ( $name eq "idttemplatepath" ) { $installer::globals::idttemplatepath = $value; }
+			if( $^O =~ /cygwin/i ) { $installer::globals::idttemplatepath =~ s/\\/\//; }
+			if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::idttemplatepath =~ s/\//\\/; }
 			if ( $name eq "idtlanguagepath" ) { $installer::globals::idtlanguagepath = $value; }
+			if( $^O =~ /cygwin/i ) { $installer::globals::idtlanguagepath =~ s/\\/\//; }
+			if (( $^O =~ /MSWin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )) { $installer::globals::idtlanguagepath =~ s/\//\\/; }
 			if ( $name eq "logfilename" ) { $installer::globals::logfilename = $value; }
 			if ( $name eq "product" ) { $installer::globals::product = $value; }
 			if ( $name eq "patch" ) { $installer::globals::patch = $value; }

solenv/bin/modules/installer/globals.pm

 	$exitlog = "";
 	$globalinfo_copied = 0;
 	$quiet = 0;
+	$nodownload = 0;
+	$writetotemp = 0;
+	$useminor = 0;
+	$followme_from_directory = 0;
+	$internal_cabinet_signing = 0;
 
 	$debug = 0;
 	$debugfilename = "debug.txt";
 	$patch = 0;
 	$patchincludepath = "";
 	$refresh_includepathes = 0;
+	$include_pathes_read = 0;
 	$patchfilelistname = "patchfilelist.txt";
 	@patchfilecollector = ();
 	$nopatchfilecollector = "";
 	$uredirgid = "";
 	$sundirgid = "";
 	
+	%sign_extensions = ("dll" => "1", "exe" => "1", "cab" => "1");
 	%treestyles = ("UREDIRECTORY" => "INSTALLURE", "BASISDIRECTORY" => "INSTALLBASIS", "OFFICEDIRECTORY" => "INSTALLOFFICE");
 	%installlocations = ("INSTALLLOCATION" => "1", "BASISINSTALLLOCATION" => "1", "OFFICEINSTALLLOCATION" => "1", "UREINSTALLLOCATION" => "1");
 	%treelayername = ("UREDIRECTORY" => "URE", "BASISDIRECTORY" => "BASIS", "OFFICEDIRECTORY" => "BRAND");
 
 	if (( $plat =~ /MSWin/i ) || (( $plat =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} eq "4nt" )))
 	{
-		$unzippath = "unzip.exe";			# Has to be in the path: r:\btw\unzip.exe
 		$zippath= "zip.exe";				# Has to be in the path: r:\btw\zip.exe
 		$checksumfile = "so_checksum.exe";
 		$unopkgfile = "unopkg.exe";
 	}
 	elsif (( $plat =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" ))
 	{
-		$unzippath = "unzip";				# Has to be in the path: /usr/bin/unzip
 		$zippath = "zip";					# Has to be in the path: /usr/bin/zip
 		$checksumfile = "so_checksum";
 		$unopkgfile = "unopkg.exe";
 	}
 	else
 	{ 
-		$unzippath = "unzip";				# Has to be in the path: /usr/bin/unzip
 		$zippath = "zip";					# Has to be in the path: /usr/bin/zip
 		$checksumfile = "so_checksum";
 		$unopkgfile = "unopkg";

solenv/bin/modules/installer/simplepackage.pm

 
 package installer::simplepackage;
 
+# use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
 use Cwd;
+use File::Copy;
 use installer::download;
 use installer::exiter;
 use installer::globals;
 	#				$installer::globals::separator . $installer::globals::unopkgfile;
 
 	my $unopkgfile = $installer::globals::unopkgfile;
+	
+	my $unopkgexists = 1;
+	if (( $installer::globals::languagepack ) && ( ! -f $unopkgfile ))
+	{
+		$unopkgexists = 0;	
+		$infoline = "Language packs do not contain unopkg!\n";
+		push( @installer::globals::logfileinfo, $infoline);
+	}
 
 	# my $extensiondir = $officedir . $installer::globals::separator . "share" .
 	#			$installer::globals::separator . "extension" .
 				
 	my $allextensions = installer::systemactions::find_file_with_file_extension("oxt", $extensiondir);	
 
-	if ( $#{$allextensions} > -1)
+	if (( $#{$allextensions} > -1 ) && ( $unopkgexists ))
 	{
 		my $currentdir = cwd();
 		print "... current dir: $currentdir ...\n";
 
 			if ( $installer::globals::iswindowsbuild )
 			{
-                if (( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" ))
+                if ( $^O =~ /cygwin/i )
                 {
                     $localtemppath = $installer::globals::cyg_temppath;
                 }
 			my @unopkgoutput = ();
 
 			open (UNOPKG, $systemcall);
-			while (<UNOPKG>) {push(@unopkgoutput, $_); }
+			while (<UNOPKG>)
+			{
+				my $lastline = $_;
+				push(@unopkgoutput, $lastline);
+			}
 			close (UNOPKG);
 
 			for ( my $j = 0; $j <= $#unopkgoutput; $j++ ) { push( @installer::globals::logfileinfo, "$unopkgoutput[$j]"); }
 	}
 	else
 	{
-		$infoline = "No extensions located in directory $extensiondir.\n";
-		push( @installer::globals::logfileinfo, $infoline);
+		if ( ! ( $#{$allextensions} > -1 ))
+		{
+			$infoline = "No extensions located in directory $extensiondir.\n";
+			push( @installer::globals::logfileinfo, $infoline);
+		}
 	}
 
 	chdir($from);
 	my $tempdir = $installdir . "_temp" . "." . $pid;
 	my $systemcall = "";
 	my $from = "";
+	my $makesystemcall = 1;
 	my $return_to_start = 0;
 	installer::systemactions::rename_directory($installdir, $tempdir);
 
 	# creating new directory with original name
 	installer::systemactions::create_directory($installdir);
 	
-        my $archive =  $installdir . $installer::globals::separator . $packagename . $installer::globals::archiveformat;
+	my $archive =  $installdir . $installer::globals::separator . $packagename . $installer::globals::archiveformat;
 
 	if ( $archive =~ /zip$/ ) 
 	{
 		$from = cwd();
 		$return_to_start = 1;
-		chdir($tempdir);		
+		chdir($tempdir);
 		$systemcall = "$installer::globals::zippath -qr $archive .";
-		# $systemcall = "$installer::globals::zippath -r $archive .";
+		
+		# Using Archive::Zip fails because of very long path names below "share/uno_packages/cache"
+		# my $packzip = Archive::Zip->new();
+		# $packzip->addTree(".");	# after changing into $tempdir
+		# $packzip->writeToFileNamed($archive);
+		# $makesystemcall = 0;
 	}
  	elsif ( $archive =~ /dmg$/ )
 	{
 		$systemcall = "cd $tempdir; $ldpreloadstring tar -cf - . | gzip > $archive";
 	}
 
-	print "... $systemcall ...\n";
-	my $returnvalue = system($systemcall);
-	my $infoline = "Systemcall: $systemcall\n";
-	push( @installer::globals::logfileinfo, $infoline);
+	if ( $makesystemcall )
+	{
+		print "... $systemcall ...\n";
+		my $returnvalue = system($systemcall);
+		my $infoline = "Systemcall: $systemcall\n";
+		push( @installer::globals::logfileinfo, $infoline);
 		
-	if ($returnvalue)
-	{
-		$infoline = "ERROR: Could not execute \"$systemcall\"!\n";
-		push( @installer::globals::logfileinfo, $infoline);	
-	}
-	else
-	{
-		$infoline = "Success: Executed \"$systemcall\" successfully!\n";
-		push( @installer::globals::logfileinfo, $infoline);
+		if ($returnvalue)
+		{
+			$infoline = "ERROR: Could not execute \"$systemcall\"!\n";
+			push( @installer::globals::logfileinfo, $infoline);	
+		}
+		else
+		{
+			$infoline = "Success: Executed \"$systemcall\" successfully!\n";
+			push( @installer::globals::logfileinfo, $infoline);
+		}
 	}
 
 	if ( $return_to_start ) { chdir($from); }		
 		if ( $onedir->{'HostName'} )
 		{
 			my $destdir = $subfolderdir . $installer::globals::separator . $onedir->{'HostName'};
-			if ( ! -d $destdir ) { installer::systemactions::create_directory_structure($destdir); }
+			if ( ! -d $destdir )
+			{
+				if ( $^O =~ /cygwin/i ) # Cygwin performance check
+				{
+					$infoline = "Try to create directory $destdir\n";
+					push(@installer::globals::logfileinfo, $infoline);
+					# Directories in $dirsref are sorted and all parents were added -> "mkdir" works without parent creation!
+					if ( ! ( -d $destdir )) { mkdir($destdir, 0775); }
+				}
+				else
+				{
+					installer::systemactions::create_directory_structure($destdir);
+				}
+			}
 		}
 	}
 
 		$source =~ s/\$\$/\$/;
 		$destination =~ s/\$\$/\$/;
 
-		installer::systemactions::copy_one_file($source, $destination);
+		if ( $^O =~ /cygwin/i )	# Cygwin performance, do not use copy_one_file. "chmod -R" at the end
+		{
+			my $copyreturn = copy($source, $destination);
+		
+			if ($copyreturn)
+			{
+				$infoline = "Copy: $source to $destination\n";
+				$returnvalue = 1;
+			}
+			else
+			{
+				$infoline = "ERROR: Could not copy $source to $destination\n";
+				$returnvalue = 0;
+			}
 
-		if (( ! $installer::globals::iswindowsbuild ) ||
-			(( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" )))
+			push(@installer::globals::logfileinfo, $infoline);
+		}
+		else
 		{
-			my $unixrights = "";
-			if ( $onefile->{'UnixRights'} )
-			{
-				$unixrights = $onefile->{'UnixRights'};
-				
-				# special unix rights "555" on cygwin
-				if (( $^O =~ /cygwin/i ) && ( $ENV{'USE_SHELL'} ne "4nt" ) && ( $unixrights =~ /444/ )) { $unixrights = "555"; }
-				
-				my $localcall = "$installer::globals::wrapcmd chmod $unixrights \'$destination\' \>\/dev\/null 2\>\&1";
-				system($localcall);
-			}
+			installer::systemactions::copy_one_file($source, $destination);	
 		}
 	}
 
 		$infoline = "Creating Unix link: \"ln -sf $target $destination\"\n"; 
 		push(@installer::globals::logfileinfo, $infoline);
 	}
+
+	# Setting privileges for cygwin globally
+
+	if ( $^O =~ /cygwin/i )
+	{
+		installer::logger::print_message( "... changing privileges in $subfolderdir ...\n" );
+		installer::logger::include_header_into_logfile("Changing privileges in $subfolderdir:");
 	
+		my $localcall = "chmod -R 755 " . "\"" . $subfolderdir . "\"";
+		system($localcall);
+	}
+		
 	# Registering the extensions
 
 	installer::logger::print_message( "... registering extensions ...\n" );

solenv/bin/modules/installer/systemactions.pm

 		# try to remove empty directory
 				
 		my $returnvalue = rmdir $directory;
-		
+
 		if ( ! $returnvalue )
 		{
 			$infoline = "Warning: Problem with removing empty dir $directory\n";
 	}
 }
 
+##############################################################
+# Reading all files from a directory and its subdirectories
+# Version 2	
+##############################################################
+
+sub read_full_directory {
+	my ( $currentdir, $pathstring, $collector ) = @_;
+	my $item;
+	my $fullname;
+	local *DH;
+
+	unless (opendir(DH, $currentdir))
+	{
+		return;
+	}
+	while (defined ($item = readdir(DH)))
+	{
+		next if($item eq "." or $item eq "..");
+		$fullname = $currentdir . $installer::globals::separator . $item;
+		my $sep = "";
+		if ( $pathstring ne "" ) { $sep = $installer::globals::separator; }
+
+		if( -d $fullname)
+		{
+			my $newpathstring = $pathstring . $sep . $item;
+			read_full_directory($fullname, $newpathstring, $collector) if(-d $fullname);
+		}
+		else
+		{
+			my $content = $pathstring . $sep . $item;
+			push(@{$collector}, $content);
+		}
+	}
+	closedir(DH);
+	return 
+}
+
 1;

solenv/bin/modules/installer/windows/admin.pm

 use installer::globals;
 use installer::pathanalyzer;
 use installer::systemactions;
+use installer::worker;
 use installer::windows::idtglobal;
 
 #################################################################################
 	push( @installer::globals::logfileinfo, $infoline);
 
 	my $expandfile = "expand.exe";	# Has to be in the path
+
+	# expand.exe has to be located in the system directory.
+	# Cygwin has another tool expand.exe, that converts tabs to spaces. This cannot be used of course. 
+	# But this wrong expand.exe is typically in the PATH before this expand.exe, to unpack 
+	# cabinet files.
+
+	if ( $^O =~ /cygwin/i )
+	{
+		$expandfile = $ENV{'SYSTEMROOT'} . "/system32/expand.exe"; # Has to be located in the systemdirectory
+		$expandfile =~ s/\\/\//;
+		if ( ! -f $expandfile ) { exit_program("ERROR: Did not find file $expandfile in the Windows system folder!"); }
+	}
+
 	my $expandlogfile = $unpackdir . $installer::globals::separator . "expand.log";
 
 	# exclude cabinet file
 	if ( $^O =~ /cygwin/i ) {
 		my $localunpackdir = qx{cygpath -w "$unpackdir"};
 		$localunpackdir =~ s/\\/\\\\/g;
-		$systemcall = $expandfile . " " . $cabfilename . " -F:\\\* " . $localunpackdir;
+		$cabfilename =~ s/\\/\\\\/g;
+		$cabfilename =~ s/\s*$//g;
+		$systemcall = $expandfile . " " . $cabfilename . " -F:\* " . $localunpackdir;
 	}
 	else
 	{
 	my $infoline = "";
 	my $systemcall = "";
 	my $returnvalue = "";
+	
+	my $localfullmsidatabasepath = $fullmsidatabasepath;
 
 	# Export of all tables by using "*"
+
+	if ( $^O =~ /cygwin/i ) {
+		# Copying the msi database locally guarantees the format of the directory. 
+		# Otherwise it is defined in the file of UPDATE_DATABASE_LISTNAME 
+
+		my $msifilename = $localfullmsidatabasepath;
+		installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$msifilename);
+		my $destdatabasename = $workdir . $installer::globals::separator . $msifilename;
+		installer::systemactions::copy_one_file($localfullmsidatabasepath, $destdatabasename);
+		$localfullmsidatabasepath = $destdatabasename;
+		
+		chomp( $localfullmsidatabasepath = qx{cygpath -w "$localfullmsidatabasepath"} ); 
+		chomp( $workdir = qx{cygpath -w "$workdir"} ); 
+
+		# msidb.exe really wants backslashes. (And double escaping because system() expands the string.)
+		$localfullmsidatabasepath =~ s/\\/\\\\/g;
+		$workdir =~ s/\\/\\\\/g;
+
+		# and if there are still slashes, they also need to be double backslash
+		$localfullmsidatabasepath =~ s/\//\\\\/g;
+		$workdir =~ s/\//\\\\/g;
+	}
 							
-	$systemcall = $msidb . " -d " . $fullmsidatabasepath . " -f " . $workdir . " -e $tablelist";
+	$systemcall = $msidb . " -d " . $localfullmsidatabasepath . " -f " . $workdir . " -e $tablelist";
 	$returnvalue = system($systemcall);
 
 	$infoline = "Systemcall: $systemcall\n";
 	{
 		$infoline = "ERROR: Could not execute $systemcall !\n";
 		push( @installer::globals::logfileinfo, $infoline);
-		installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $fullmsidatabasepath !", "extract_tables_from_pcpfile");
+		installer::exiter::exit_program("ERROR: Could not exclude tables from pcp file: $localfullmsidatabasepath !", "extract_tables_from_pcpfile");
 	}
 	else
 	{
 	my $wordcount = 4;  # Unpacked files
 	my $lastprinted = get_sis_time_string();
 	my $lastsavedby = "Installer";
+
+	my $localmsidatabase = $msidatabase;
+	
+	if( $^O =~ /cygwin/i )
+	{
+		$localmsidatabase = qx{cygpath -w "$localmsidatabase"};
+		$localmsidatabase =~ s/\\/\\\\/g;
+		$localmsidatabase =~ s/\s*$//g;
+	}
 							
-	$systemcall = $msiinfo . " " . "\"" . $msidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
+	$systemcall = $msiinfo . " " . "\"" . $localmsidatabase . "\"" . " -w " . $wordcount . " -s " . "\"" . $lastprinted . "\"" . " -l $lastsavedby";
 	push(@installer::globals::logfileinfo, $systemcall);
 	$returnvalue = system($systemcall);
 
 	
 	# Unpack all cab files into $helperdir, cab files must be located next to msi database
 	my $installdir = $databasepath;
+
+	if ( $^O =~ /cygwin/i ) { $installdir =~ s/\\/\//g; } # backslash to slash
+	
 	installer::pathanalyzer::get_path_from_fullqualifiedname(\$installdir);
+
+	if ( $^O =~ /cygwin/i ) { $installdir =~ s/\//\\/g; } # slash to backslash
+
 	my $databasefilename = $databasepath;
 	installer::pathanalyzer::make_absolute_filename_to_relative_filename(\$databasefilename);
 
 
 	for ( my $i = 0; $i <= $#{$cabfiles}; $i++ )
 	{
-		my $cabfile = $installdir . $installer::globals::separator . ${$cabfiles}[$i];
+		my $cabfile = "";
+		if ( $^O =~ /cygwin/i )
+		{
+			$cabfile = $installdir . ${$cabfiles}[$i];
+		}
+		else
+		{
+			$cabfile = $installdir . $installer::globals::separator . ${$cabfiles}[$i];
+		}
 		unpack_cabinet_file($cabfile, $unpackdir);
 	}
 	

solenv/bin/modules/installer/windows/idtglobal.pm

 		my $line = $actionname . "\t" . $actioncondition . "\t" . $actionposition . "\n";
 		push(@{$installtable}, $line);
 
-        $infoline = "Added $actionname CustomAction into table $customactionidttablename (NO_FILE has been set)\n";
+        $infoline = "Added $actionname CustomAction into table $installtablename (NO_FILE has been set)\n";
     	push(@installer::globals::logfileinfo, $infoline);
         return;
 	}
 	{
 		my $line = ${$sequencetable}[$i];
 	
-		if ( $line =~ /^\s*(\w+)\t.*\t\s*(\d+)\s$/ )	# matching only, if position is a number!
+		if ( $line =~ /^\s*([\w\.]+)\t.*\t\s*(\d+)\s$/ )	# matching only, if position is a number!
 		{
 			my $compareaction = $1;
 			my $localposition = $2;
 
 	for ( my $i = 0; $i <= $#{$sequencetable}; $i++ )
 	{
-		if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*POSITIONTEMPLATE_end\s*$/ )
+		if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*POSITIONTEMPLATE_end\s*$/ )
 		{
 			my $customaction = $1;
 			$lastposition = $lastposition + 25;
 		
 		for ( my $i = 0; $i <= $#{$sequencetable}; $i++ )
 		{
-			if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ )
+			if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ )
 			{
 				my $onename = $1;
 				my $templatename = $2;
 
 		for ( my $i = 0; $i <= $#{$sequencetable}; $i++ )
 		{
-			if ( ${$sequencetable}[$i] =~ /^\s*(\w+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ )
+			if ( ${$sequencetable}[$i] =~ /^\s*([\w\.]+)\t.*\t\s*(POSITIONTEMPLATE_.*?)\s*$/ )
 			{
 				my $customactionname = $1;
 				my $fulltemplate = $2;

solenv/bin/modules/installer/windows/msiglobal.pm

 		{
 			if ( $allvariables->{'PACKAGEVERSION'} =~ /^\s*(\d+)\.(\d+)\.(\d+)\s*$/ ) { $productminor = $2; }
 		}
+				
 		$productversion = $productversion . "\." . $productminor . "\." . $installer::globals::buildid;	
 	}
-
+	
 	$installer::globals::msiproductversion = $productversion;
 	
 	# Setting $installer::globals::msimajorproductversion, to differ between old version in upgrade table
 		while (<F>)
 		{
 			m/^([^\t]+)\t([^\t]+)\t((.*)\|)?([^\t]*)/;
-			print "AAA1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n";
+			print "OUT1: \$1: $1, \$2: $2, \$3: $3, \$4: $4, \$5: $5\n";
 			next if ("$1" eq "$5") && (!defined($3));
 			my $lc1 = lc($1);
 			
 			next if (!defined($3));
 			my $lc1 = lc($1);
 
-			print "AAA2: \$1: $1, \$2: $2, \$3: $3\n";
+			print "OUT2: \$1: $1, \$2: $2, \$3: $3\n";
 
 			if ( exists($installer::globals::saved83dirmapping{$1}) )
 			{

solenv/bin/modules/installer/windows/msp.pm

 	
 	my $olddatabase = installer::windows::admin::make_admin_install($oldinstallsetdatabasepath, $oldinstallpath);
 	my $newdatabase = installer::windows::admin::make_admin_install($newinstallsetdatabasepath, $newinstallpath);
+
+	if ( $^O =~ /cygwin/i ) {
+		$olddatabase = qx{cygpath -w "$olddatabase"};