#! /usr/bin/perl
#
# $Header: //sapdb/TOOLSRC/develop/sys/src/BuildPackage/New.pm#35 $
# $DateTime: 2003/02/12 12:52:19 $
# $Change: 36609 $
#
# Desc: tool to build several sap db packages
#
#    ========== licence begin LGPL
#    Copyright (C) 2002 SAP AG
#
#    This library is free software; you can redistribute it and/or
#    modify it under the terms of the GNU Lesser General Public
#    License as published by the Free Software Foundation; either
#    version 2.1 of the License, or (at your option) any later version.
#
#    This library is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#    Lesser General Public License for more details.
#
#    You should have received a copy of the GNU Lesser General Public
#    License along with this library; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#    ========== licence end
#


package BuildPackage::New;

use Getopt::Long;
use BuildPackage::GetFilesFromCDImages; # needed for XML stuff -> getting PCR 32/64 bit
use BuildPackage::Tools;
use BuildPackage::Vars;
use BuildPackage::LCPool;


#
#	IMPORTANT CHANGE:
#	use PackDefs and LCPool::Items from release tree instead of DevTool tree 
#
	
local @INC = ("$WRK/fast/install",@INC);
if($LC_ROOT =~ /\S/){
	@INC = ($LC_ROOT,@INC);
}

require BuildPackage::PackDefs;
import BuildPackage::PackDefs;

require BuildPackage::LCPool::Items;
import BuildPackage::LCPool::Items;	

BuildPackage::Tools::setErrMsgHandler(\&err);
BuildPackage::Tools::setMsgHandler(\&msg);


my @all_files;


sub start{
	local @ARGV=@_;
	my @argbuf = @ARGV;
	
	my %opt_ctrl=(
			'h' => \$opt_help,
			'help' => \$opt_help,
			'profile=s' => \$opt_profile,
			'package=s' => \$opt_package,
			'format=s' => \$opt_format,
			'rpm' => \$opt_rpm,
			'components' => \$opt_components,
			'ignore_errors' => \$opt_ignore_errors,
			'single_pcr' => \$opt_single_pcr,
			'finalize' => \$opt_finalize,
			#'no_archive' => \$opt_no_archive,
			'ftp' => \$opt_ftp,
			'var=s' => \$opt_var

	);
	
	Getopt::Long::Configure ('no_pass_through');
	if(!GetOptions(%opt_ctrl) or $opt_help){
		msg ("usage: buildpackage [-h] [-ftp] [-no_archive] [-profile <profile>] [-package <package list>] [-format tgz|sar] [-finalize]\n\n");
		exit 0;
	}
	
	
	if($opt_var){
		my %vars;
		foreach my $var_string (split(',',$opt_var)){
			my ($varname,$varvalue) = ($var_string =~ /^([^=]+)=([^=]*)$/);
			$varname =~ /\S/ and $vars{$varname} = $varvalue;
		}
		SetVars(\%vars,\&err);
	}

	# tiny helper functions
	sub timestamp{
		my($sec,$min,$hour,$day,$mon,$year)=localtime(time);
		$mon++;
		$sec="0$sec" if(length($sec)==1);
		$min="0$min" if(length($min)==1);
		$hour="0$hour" if(length($hour)==1);
		$day="0$day" if(length($day)==1);
		$mon="0$mon" if(length($mon)==1);
		$year=$year+1900;
		return "$year$mon$day$hour$min$sec";
	}

	-d "$WRK/fast/install" or makedir("$WRK/fast/install",0775);
	my $count = '';
	while(1){
		$logfilename="$WRK/fast/install/buildpackage_".timestamp.$count.'.log';
		-f $logfilename or last;
		$count++ unless $count eq ''; 
		$count = 0 if $count eq '';
	}
	
	open(LOG, ">$logfilename") || err ("cannot create logfile\n");
	msg("call: ".join(' ',@argbuf)."\n");
	sub err{
		my ($text)=@_;
		if($opt_ignore_errors){
			print STDERR "ERR: $text";
			print LOG "ERR: $text";
		}
		else{
			print LOG "ERR: $text";
			close(LOG);
			print STDERR $text;
			exit -1;
		}
	}

	sub msg{
		my ($text)=@_;
		print LOG $text;	
		print $text;
	}

	if($^O =~ /linux/ and ($opt_format =~ /^rpm$/i or ($opt_components and $opt_rpm ))){
		require BuildPackage::RPM;
		import BuildPackage::RPM;
		BuildPackage::RPM::setErrMsgHandler(\&err);
		BuildPackage::RPM::setMsgHandler(\&msg);
		my @rpms = packRPM();
		push @all_files,@rpms;
		exit 0 unless $opt_components;	
	}




	if($opt_ftp){
		SetVars({'USE_FTP' => 1},\&err);
	}


	BuildPackage::LCPool::initPackage('err' => \&err,'msg' => \&msg);
	

	sub existInList{
		my ($packname,@packages)=@_;
		foreach my $hrPack (@packages){
			$packname eq ${%$hrPack}{'name'} and return 1; 
		}
		return 0;
	}
	
		
	#sub copyPCR{
	#	BuildPackageOld::OldPCR();
	#}	


	my @packages;
	
	#
	#define replacements -> for replacing strings in signature file and package script
	#	
	
	my %replacements = (
		'§RELEASE' => "$MAJ.$MIN.$COR.$BUILD",
		'§APORELEASE' => "$APO_REL.$APO_BUILD",
		'§LC_RELEASE' => "$LC_RELEASE",
		'§PACKVERS' => "$RUNTIME_VERSION", # used for names/pathes of PCR and SDK packages 
		'§BIT' => $BIT,
		'§SOEXT' => '.'.$SOEXT,
		'§EXEXT' => $EXEEXT
	);
	
	
	#foreach my $sym (keys(%BuildPackage::New::)){
	#	local *value = $BuildPackage::New::{$sym};
	#	defined $value and print "$sym = $value\n";
	#} 	

		
	#
	# select packages to build
	# with profile option
	#
	
	if($opt_profile and $opt_profile ne 'all' ){
		my @profiles = split(',',$opt_profile);
		foreach my $profile (@profiles){
			exists $profiles{$profile} or err ("no such profile: \"".$profile."\"\n");
			my @prof_pack;
			foreach my $pack (@{$profiles{$profile}}){
				defined $pack or next;
				my $found = 0;
				foreach my $packref (@allpackages){
					if($pack eq ${%$packref}{'name'}){
						$found=1;
						existInList($pack,@packages) and last;
						push @packages,$packref;
						last;
					}
				}
				if($found){
					push @prof_pack,$pack;
				}
				else{
					err("no such package: \"$pack\"\n");
				}
			}
			msg ("found for \"$profile\":\n");
			foreach my $packnam (@prof_pack){
				msg ("\t$packnam\n");
			}
			msg ("\n");
		}
		if ($APOMAKE and $opt_profile ne 'APO LiveCache'){
			err("LC APPS MAKE ENVIRONMENT: profile \"APO LiveCache\" allowed only\n");
		}
		if(!$APOMAKE and $opt_profile =~ /APO\s*LiveCache/){
			err("NO LC APPS MAKE ENVIRONMENT: profile \"APO LiveCache\" not allowed\n");
		}
			
	}
	
	
	#
	# select packages to build
	# with package option
	#
	
	if($opt_package){
		my @packs = split(',',$opt_package);
		foreach my $pack (@packs){
			my $found = 0;
			foreach my $packref (@allpackages){
				if($pack eq ${%$packref}{'name'}){
					push @packages,$packref;
					$found=1;
					last;
				}
				elsif($pack eq 'APO COM'){
					if(${%$packref}{'name'} eq 'APO LC APPS'){
						push @packages,$packref;
						$found = 1;
						last;
					}
				}
			}
			$found || err("no such package: \"$pack\"\n");
		}
		if ($APOMAKE and ($opt_package ne 'APO COM' and $opt_package ne 'APO LC APPS')){
			err("LC APPS MAKE ENVIRONMENT: package \"APO COM\" / \"APO LC APPS\" allowed only\n");
		}
		if(!$APOMAKE and $opt_package =~ /APO\s*COM|APO\s\LC\sAPPS/){
			err("NO LC APPS MAKE ENVIRONMENT: package \"$opt_package\" not allowed\n");
		}
	}
	
	
	sub packageInside{
		my ($packages,$package) = @_;
		foreach my $pack (@$packages){
			return 1 if (${%$pack}{'name'} eq ${%$package}{'name'});	
		}
		return 0;
	}

	my @profile_packages = @packages;

	if($opt_profile eq 'all' || $opt_components){
		unless($APO_MAKE){
			#@packages = (); # init
			foreach my $packref (@allpackages){
				#packageInside
				push @packages,$packref if ((${%$packref}{'name'} ne 'APO COM' and ${%$packref}{'name'} ne 'APO LC APPS') and not packageInside(\@packages,$packref)); 
			}
		}
	}



	#
	# select all packages to build if no option set
	#
	if($#packages == -1){
		err("no package selected\n");
	}
	
	
	# print out packages
	msg ("try to build following packages: \n");
	foreach $hrPack (@packages){
		msg ("\t".${%$hrPack}{'name'}."\n");
		if(!$APOMAKE and ${%$hrPack}{'name'} =~ /APO\s*COM|APO\sLC\sAPPS/){
			err("NO LC APPS MAKE ENVIRONMENT: package \"".${%$hrPack}{'name'}."\" not allowed\n");
		}
		if ($APOMAKE and (${%$hrPack}{'name'} ne 'APO COM' and ${%$hrPack}{'name'} ne 'APO LC APPS')){
			err("LC APPS MAKE ENVIRONMENT: package \"APO COM\" / \"APO LC APPS\" allowed only\n");
		}
		if($hrPack->{'name'} eq 'JDBC'){
			require SAPDB::Install::Jar;
			import SAPDB::Install::Jar;
		}
	}
	msg ("\n"); 


	my $packpath = $PACKAGEPATH.'/packages';

	if($APOMAKE){
		$packpath = "$LC_OWN/sys/src/lcsrc/packages" unless(-f $PACKAGEPATH.'/packages/apocom/PACKAGEDATA');
	}



	#
	# test needed files:
	# 
	
	my $include_pcr = 0;
	foreach my $package (@packages){
		foreach my $file (${%$package}{'filelist'},${%$package}{'script'},'PACKAGEDATA'){
			-f $packpath.'/'.${%$package}{'subdir'}.'/'.$file || err($packpath.'/'.${%$package}{'subdir'}.'/'.$file.' [package "'.${%$package}{'name'}."\"] not found\n");
		}
		$include_pcr = 1 if ${%$package}{'name'} =~ /^PCR/;
	}

	my @oldpcr_packages = (); 
	
	if($include_pcr && !$opt_single_pcr){
		# copy pcr packages
		BuildPackage::GetFilesFromCDImages::setErrMsgHandler(\&err);
		BuildPackage::GetFilesFromCDImages::setMsgHandler(\&msg);
		my @files = grep {/\.TGZ$/} getFiles("$MAJ.$MIN.$COR.$BUILD",$OWN);
		push(@oldpcr_packages,@files) unless $opt_profile =~ /SDK|Develop|Precompiler/;
		push @all_files,@oldpcr_packages;
	}
	
	
	#
	# get niping for APO COM package
	#

	if($APOMAKE && defined $LC_ROOT){
		my $src = "$LC_OWN/sys/src/lcsrc/sap/niping$EXEEXT";
		my $dst = "$INSTROOT/sap/niping$EXEEXT";
		if($^O=~/mswin/i){
			my $winsrc = $src;
			my $windst = $dst;
			$winsrc=~s/\//\\/g;
			$windst=~s/\//\\/g;
			`copy $winsrc $windst`;
		}
		else{
			`cp -p $src $dst`;
		}
		-f $dst or err("cannot copy $src -> $dst\n");
	}


	#
	# build packages
	#
	
	foreach my $package (@packages){
		
		#
		# make sure that there is no old stuff 
		#

		-d $BUILDROOT and (deltree($BUILDROOT) or err("cannot remove buildroot\n"));
		makedir($BUILDROOT,0775) or err("cannot create buildroot\n");
		
		#
		#
		#

		my $JDBC_version;
		if ($package->{'name'} eq 'JDBC'){
			my ($rc_key,$rc_value);
			if($^O =~ /aix/i){
				sub JarBuildString {
					my ($filename) = @_;

					return undef unless (-r $filename);

					my $in = SAPDB::Install::Jar->new ();

					$in->OpenArchive ($filename);
					$in->Open ('META-INF/MANIFEST.MF');

					my $buildstr;
					for (;;) {
						my $line = $in->ReadLine ();
						last unless defined ($line);

						($buildstr) = ($line =~ /^Implementation-Version:\s"(.+)"$/);
						last if (defined $buildstr);

						($buildstr) = ($line =~ /^Implementation-Version:\s(.+)$/);
						last if (defined $buildstr);
					}

					$in->Close ();
					$in->CloseArchive ();
		
					return undef unless (defined $buildstr);

					my ($rel, $build);

					($rel, $build) =
					($buildstr =~ /(\d\.\d\.\d+)\s+Build:\s+(\d[\d|-]*)/);

					unless (defined $rel && defined $build) {
						($rel, $build) =
						($buildstr =~ /(\d\.\d\.\d+)\s+Build\s+(\d[\d|-]*)/);
					}

					unless (defined $rel && defined $build) {
						return undef;
					}

					$build =~ s/-$//;

					return ("JAR  ".$rel." Build: ".$build);
				}

				sub JarBuildInfo {
					my ($filename) = @_; 
					return undef unless (-r $filename);
				
					my $buildstr = JarBuildString ($filename);
					return undef unless (defined $buildstr);
				
					my (@info) =
					($buildstr =~ /^JAR\s+(\d+)\.(\d+)\.(\d+)\s+Build:\s+(\d+)/);
					return undef unless (defined $info[0] && defined $info[1] &&
										defined $info[2] && defined $info[3]);
	
					#
					# convert to integer
					#
					$info[3] += 0;
					return ("Build" => \@info);
				}
							
				($rc_key,$rc_value) = JarBuildInfo("$INSTROOT/runtime/jar/sapdbc.jar");
			}
			else{
				($rc_key,$rc_value) = SAPDB::Install::Jar::JarBuildInfo("$INSTROOT/runtime/jar/sapdbc.jar");
			}	
			my ($jmaj,$jmin,$jcor,$jbuild) = @$rc_value;
			$jcor = "0$jcor" if length($jcor) == 1;
			$jbuild = "0$jbuild" if length($jbuild) == 1;
			$JDBC_version = "$jmaj.$jmin.$jcor.$jbuild";
			msg("set JDBC version to $JDBC_version\n");
		} 
		else{
			$JDBC_version = undef;
		}
		
		
		
		#	
		# copy and change script and signature 
		#
		
		foreach my $file (${%$package}{'script'},'PACKAGEDATA'){
			open(IN,$packpath.'/'.${%$package}{'subdir'}.'/'.$file) or err('cannot open '.$packpath.'/'.${%$package}{'subdir'}."/$file\n");
			open (OUT,">$BUILDROOT/$file") or err("cannot create $BUILDROOT/$file\n");
			while(<IN>){
				chomp;
				foreach my $string (keys(%replacements)){
					s/§RELEASE/$JDBC_version/g if $JDBC_version =~ /\S/;
					s/$string/$replacements{$string}/g;
				}
				print OUT "$_\n" or err("cannot write into $BUILDROOT/$file\n");
			}
			close(IN);
			close(OUT);	
		}
	
		if(exists ${%$package}{'additional_installer_files'}){
			push @all_files ,@{${%$package}{'additional_installer_files'}};
			push @additional_installer_files, @{${%$package}{'additional_installer_files'}};
		}
		
		# call special package function if exists, at the moment only for pcr packages needed
		#exists ${%$package}{'specialFunc'} and &{${%$package}{'specialFunc'}}($package); 

		#
		# copy files, generate md5sums and change filelist (attach checksums)
		#
		
		open(IN,$packpath.'/'.${%$package}{'subdir'}.'/'.${%$package}{'filelist'}) or err('cannot open '.$packpath.'/'.${%$package}{'subdir'}.'/'.${%$package}{'filelist'}."\n");
		open(OUT,">$BUILDROOT/".${%$package}{'filelist'}) or err("cannot create $BUILDROOT/".${%$package}{'filelist'}."\n");
		while(<IN>){
			chomp;
			/^#/ && next;
			
			my $src = $_;
			if(exists ${%{${%$package}{'FileMappings'}}}{$_}){
				$src = ${%{${%$package}{'FileMappings'}}}{$_};
			}
			
			if(${%$package}{'name'} eq 'APO COM' or ${%$package}{'name'} eq 'APO LC APPS'){
				$src = "sap/$src";
			}
				
			$src = "$USR/$src";
			
			my $dst="$BUILDROOT/$_";
			my $dir = $dst;
			$dir=~s/\/[^\/]*$//;
			-d $dir or makedir($dir,0775) or err("cannot create directory $dir\n");
			
			if($^O=~/mswin/i){
				my $winsrc = $src;
				my $windst = $dst;
				$winsrc=~s/\//\\/g;
				$windst=~s/\//\\/g;
				`copy $winsrc $windst`;
			}
			else{
				`cp -p $src $dst`;
			}
			-f $dst or err("cannot copy $src -> $dst\n");
			my $md5sum=getMD5Sum($dst) or err("cannot get md5sum of $dst\n");
			print OUT "\"$_\" $md5sum\n" or err("cannot write into $BUILDROOT/".${%$package}{'filelist'}."\n");
		}
		close(IN);
		close(OUT);
		
		if(exists ${%$package}{'add_files'}){
			foreach my $file (@{${%$package}{'add_files'}}){
				my ($path) = ($file =~ /^(\S+)\/[^\/]+$/);
				my $dest = ($path =~ /\S/ ? "$BUILDROOT/$path" : $BUILDROOT);
				copy("$INSTROOT/$file",$dest,1);
			}
		}
		
		
		
		chdir("$BUILDROOT") or err("cannot change into directory $BUILDROOT\n");
		my $tarname="$PACKAGEPATH/".${%$package}{'archive'};
		
		# 
		# generate list of files and folders to pack
		# -> sequencing is important for performance of installer
		#
		
		my $packlist = 'PACKAGEDATA '.${%$package}{'script'}.' ' .${%$package}{'filelist'};
		opendir(DH,'.') || err("cannot open directory: $!\n");
		my @content = readdir(DH);
		closedir(DH);
		
		foreach (@content){
			(/^PACKAGEDATA$/ or /^${%$package}{'script'}$/ or /^${%$package}{'filelist'}$/ or /^\.{1,2}$/) and next;
			$packlist="$packlist $_"; 
		}
		
		#
		# pack archive
		#
		
		msg ("pack archive $tarname\n"); 
		#print "COMMAND: tar -cvpzf $tarname $packlist\n";
		if($^O =~ /mswin/i){
			do_cmd("tar -cvpf - $packlist | gzip -c -9 >$tarname");
		}
		else{
			do_cmd("gtar -cvpzf $tarname $packlist");
		}
		$? == 0 or err("tar error while packing \"".${%$package}{'name'}."\"\n");
		-f $tarname or err("no archive \"$tarname\" produced\n");
		chdir('..'); # leave buildroot
		push @all_files,${%$package}{'archive'};
	}

	push @all_files,@installer_files;
	push @installer_files,@additional_installer_files;
	
	if( (not $opt_profile =~ /\S/) || $opt_no_archive){
		if($opt_finalize){
			$EM_MAKE || err("no valid productive environment to finalize\n");	
			
			#
			# find free pool slot
			#

			my $slot = findFreePoolSlot($LC_POOL_DIR,'changelist.log',$LC_STATE eq 'DEV' ?  4 : 3);
			
			my $new_dir = $slot;
			
			#
			# copy package into pool directotry
			#
			
			
			msg("copy $WRK/fast/install/$package_name -> $new_dir/$package_name\n");
			
			my $vmake_gid;
			unless($^O =~ /mswin/i){
				$vmake_gid = getgrnam('vmake') || err("unknown group \"vmake\"\n");
			}
			
			-d $new_dir or makedir($new_dir,0775,\$undefined,\$vmake_gid) or err("cannot create directory $new_dir: $!\n");
			
			
			foreach my $package (@all_files){
				msg("copy $WRK/fast/install/$package -> $slot/$package\n");
				copy("$WRK/fast/install/$package",$slot,1) || err("cannot copy: $!");
			}
			
			copyItems("$WRK/fast/install",$slot,['BuildPackage/PackDefs.pm']);

			copy("$OWN/changelist.log",$slot);

			#
			# change latest link
			#
				
			linkSlot($slot,'LastBuild');
		}		
		exit 0;
	}


	#
	# build liveCache + APO COM package
	#
	
	if ($APOMAKE && $opt_profile eq 'APO LiveCache'){
		my $lc_package = "$LC_OWN/$LC_PACK_NAME"; 
		-f $lc_package || err ("no liveCache ($lc_package) found\n");
		if($^O =~ /mswin/i){
			$lc_package =~ s/\//\\/g;
		}
		
		#
		# make sure that there is no old stuff 
		#
		
		-d $BUILDROOT and (deltree($BUILDROOT) or err("cannot remove buildroot\n"));
		my $inner_subdir = $BUILDROOT.'/'.$profile_data{$opt_profile}->{'inner_subdir'};
		makedir($BUILDROOT,0775) or err("cannot create buildroot\n");
		chdir($BUILDROOT) || err("cannot change into buildroot\n");
		do_cmd("SAPCAR -xvf $lc_package");
		unless(-d $LC_INNER_SUBDIR){
			
			#
			#	workaround for compatibility problems 
			#	with changed os name true64 -> tru64
			#
				
			my $inner_subdir_true64 = $LC_INNER_SUBDIR;
			$inner_subdir_true64 =~ s/tru64/true64/;
			-d $inner_subdir_true64 or err("no inner subdir \"$LC_INNER_SUBDIR\" found\n");
			$LC_INNER_SUBDIR = $inner_subdir_true64;
		}
		rename($LC_INNER_SUBDIR,$profile_data{$opt_profile}->{'inner_subdir'}) or err("cannot rename inner subdir\n");
		
		my ($lcapps_package) = grep {/\.TGZ$/ and not /^SDBINST/ } @all_files;
				
		copy("$WRK/fast/install/$lcapps_package",$BUILDROOT.'/'.$profile_data{$opt_profile}->{'inner_subdir'},1) || err ("cannot copy APO LC APPS  package\n");
		my $package_name = $profile_data{$opt_profile}->{'archive_name'}.'.SAR';
		do_cmd("SAPCAR -cvf $WRK/fast/install/$package_name ".$profile_data{$opt_profile}->{'inner_subdir'});
		-f "$WRK/fast/install/$package_name" &&
		msg("package $WRK/fast/install/$package_name successfully packed\n");
		
		
		if($opt_finalize){
		
			#
			# find free pool slot
			#

			my $slot = findFreePoolSlot($APO_POOL_DIR,$package_name,3);
			
			my $new_dir = $slot;
			
			#
			# copy package into pool directotry
			#
			
			
			msg("copy $WRK/fast/install/$package_name -> $new_dir/$package_name\n");
			
			my $vmake_gid;
			unless($^O =~ /mswin/i){
				$vmake_gid = getgrnam('vmake') || err("unknown group \"vmake\"\n");
			}
			
			-d $new_dir or makedir($new_dir,0775,\$undefined,\$vmake_gid) or err("cannot create directory $new_dir: $!\n");
			
			
			copy("$OWN/changelist.log",$new_dir,1) || err("cannot copy changelist.log: $!\n");
			
			copy("$WRK/fast/install/$package_name",$new_dir,1) || err("cannot copy: $!\n");		
			
			copy("$OWN/make.id",$new_dir,1) || err("cannot copy make.id: $!\n");

			#
			#	copy components
			#
						
			my $components = $new_dir.'/'.$LCAPPS_COMPONENTS_DIR;
			-d $components or makedir($components,0775,\$undefined,\$vmake_gid) or err("cannot create directory $components: $!\n");
			copy("$WRK/fast/install/$lcapps_package",$components,1) || err("cannot copy $WRK/fast/install/$lcapps_package -> $components: $!\n");		
			
			
			#
			# change latest link
			#
				
			linkSlot($slot,'LastBuild');
			
				
		}
		close(LOG);
		exit 0;
	
	}	
	
	
	#
	# build packages without APO COM
	# LC or other SAP DB package
	#

	my $PACKNAME = $opt_profile;
	if(exists $profile_in_name{$opt_profile}){
		$PACKNAME = $profile_in_name{$opt_profile};
	}
	
	
	
	$PACKNAME =~ tr/[A-Z]/[a-z]/;
	$PACKNAME =~ s/\s/_/g;
	
	my $name_COR = $COR;
	my $name_BUILD = $BUILD;
	$name_COR =~ s/^0*//;
	$name_COR eq '' and $name_COR = '0';
	$name_BUILD =~ s/^0*//;
	$name_BUILD eq '' and $name_BUILD = '0';
	
	
	$packagename="sapdb-$PACKNAME-$OS-".$BIT."bit-$ARCH-".$MAJ.'_'.$MIN.'_'.$name_COR.'_'.$name_BUILD;
	my $package_name = $packagename.'.sar'; 

	my $packages;
	@profile_files;
	foreach my $package (@profile_packages){
		$packages .= ' '.${%$package}{'archive'};
		push @profile_files,${%$package}{'archive'};
	}

	
	my $ext='tgz';
	my $exec_ext;
	$exec_ext = '.exe' if ($^O =~ /mswin/i);
	my $errtxt;
	my $inner_subdir;
	if($opt_format eq 'sar' || $EM_MAKE){
		$ext='sar';
		#print "\$opt_profile = $opt_profile\n";
		#foreach my $key (keys(%profile_data)){
		#	print "found member $key in \%profile_data\n";
		#}
		
		if(exists $profile_data{$opt_profile}){
			$ext =~ tr/[a-z]/[A-Z]/;
			$PACKNAME = $profile_data{$opt_profile}->{'archive_name'};
			$packagename = $PACKAGEPATH.'/'.$profile_data{$opt_profile}->{'archive_name'}.'.'.$ext;
			$inner_subdir = $PACKAGEPATH.'/'.($profile_data{$opt_profile}->{'inner_subdir'});
			if(-d $inner_subdir){
				deltree($inner_subdir) or err("cannot delete existing $inner_dir\n:$!\n");
			}
			else{
				makedir($inner_subdir,0775) or err("cannot create directory $inner_subdir\n");
			}
			my @archive_files = (@profile_files,@installer_files,@oldpcr_packages);
			copyItems($PACKAGEPATH,$inner_subdir,\@archive_files); 
			chdir($PACKAGEPATH) or err("cannot change into dir $PACKAGEPATH\n");
			my $cmd = "SAPCAR -cvf $PACKNAME.$ext ".$profile_data{$opt_profile}->{'inner_subdir'};	
			do_cmd($cmd);
			$? == 0 || err("sapcar error: $!\n");
			deltree($inner_subdir)  or err("cannot delete $inner_dir\n:$!\n");;
		}
		else{	
			chdir($PACKAGEPATH) or err("cannot change into dir $PACKAGEPATH\n");
			$packagename="$PACKAGEPATH/$packagename.$ext";
			my $cmd = "SAPCAR -cvf $packagename SDBRUN$exec_ext SDBINST$exec_ext ";
			$cmd .= "SDBUPD$exec_ext " if($packages =~ /SAPDBKRN.TGZ/);
			$cmd .= "SDBINST.TGZ $packages ".join(' ',@oldpcr_packages); 
			if($^O =~ /mswin/i){
			$cmd .= (exists $ENV{'BIT64'} || 
					($MAJ >= 7 && $MIN >= 4 && $COR >= 3) || 
					($MAJ >= 7 && $MIN >= 4 && $COR == 2 && $BUILD >= 4) || 
					($MAJ >= 7 && $MIN >= 4 && $COR == 1 && $BUILD >= 20)) ? ' perl56.dll' : ' perl.dll';
			}
			do_cmd($cmd);
			$? == 0 || err("sapcar error: $!\n");
		}
	}
	else{
		$packagename="$PACKAGEPATH/$packagename.$ext";
		my $tar = 'gtar';
		$tar = 'tar' if $^O =~ /mswin/i;
		my $cmd = "$tar -cvpzf $packagename SDBRUN$exec_ext SDBINST$exec_ext "; 
		$cmd .= "SDBUPD$exec_ext " if($packages =~ /SAPDBKRN.TGZ/);
		$cmd .= "SDBINST.TGZ $packages ".join(' ',@oldpcr_packages); 
		
		if($^O =~ /mswin/i){
			$cmd .= (exists $ENV{'BIT64'} || 
					($MAJ >= 7 && $MIN >= 4 && $COR >= 3) || 
					($MAJ >= 7 && $MIN >= 4 && $COR == 2 && $BUILD >= 4) || 
					($MAJ >= 7 && $MIN >= 4 && $COR == 1 && $BUILD >= 20))  ? ' perl56.dll' : ' perl.dll';
		}
		do_cmd($cmd);
		$? == 0 || err("tar error: $!\n");
	
	} 
	if(-f $packagename){
		msg ("packed $packagename successfully\n");
	}
	else{
		err ("cannot pack mainpackage \"$packagename\": $errtxt\n");
	}
	if($opt_finalize){
		
		if($EM_MAKE){
			if($opt_profile eq 'Server'){
			
				$package_name = $profile_data{$opt_profile}->{'archive_name'}.'.SAR';	


				#
				# find free pool slot
				#
	
				my $slot = findFreePoolSlot($LC_POOL_DIR,$package_name,($LC_STATE eq 'DEV' ?  4 : 3),'^SAPDB'.$MAJ.$MIN.$COR.'_\d\d.SAR$');
				defined $slot or err("cannot find free pool slot\n");
				my $new_dir = $slot;	
				
				my $vmake_gid;
				unless($^O =~ /mswin/i){
					$vmake_gid = getgrnam('vmake') || err("unknown group \"vmake\"\n");
				}


				-d $new_dir or makedir($new_dir,0775,\$undefined,\$vmake_gid) or err("cannot create directory $new_dir: $!\n");
			
			
				foreach my $src_dir (keys(%lcitems)){
					my $dest_dir = $new_dir;
					exists ${%{$lcitems{$src_dir}}}{'subdir'} and $dest_dir .= '/'.$lcitems{$src_dir}->{'subdir'};
					copyItems($src_dir,$dest_dir,$lcitems{$src_dir}->{'items'});				
					
				}
				
				if(defined @BuildPackage::LCPool::Items::simulator_list){
					open(FD,">$new_dir/simul.lst") or err("cannot create simulator file list $new_dir/simul.lst: $!\n");	
					foreach my $file (@BuildPackage::LCPool::Items::simulator_list){
						$file =~ /\S/ or next;
						print FD $file."\n";
					}	
					close(FD);
				} 
								
				
				#
				# copy SAP DB components
				#
				if($opt_components){
					my $components_dir = $slot."/$SAPDB_COMPONENTS_DIR";
					-d $components_dir or (makedir($components_dir,0775) or err("cannot create SAP DB components directory\n"));
					foreach my $file (@all_files){
						msg("copy $WRK/fast/install/$file -> $components_dir/$file\n");
						copy("$WRK/fast/install/$file",$components_dir,1) || err("cannot copy: $!");				
					}
					copyItems("$WRK/fast/install",$components_dir,['BuildPackage/PackDefs.pm']);
				}

				#
				# copy package into pool directotry
				#
		
				msg("copy $WRK/fast/install/$package_name -> $slot/$package_name\n");
				copy("$WRK/fast/install/$package_name",$slot,1) || err("cannot copy: $!");		
			
							
				#
				# change latest link
				#
							
				linkSlot($slot,'LastBuild');
			
			}
			close(LOG);
			exit 0;									
		}
		
		if($USE_FTP){
			err("no ftp access rights to put package to CD-Images\n");
		}
		
		msg("copy $packagename.$ext to CD-Images\n");
		my $ospath;
		if(exists $ENV{'BIT64'} or $^O =~ /osf/i){
			$ospath = $OS64_PATH;
		}
		else{
			$ospath = $OS32_PATH;
		}
		my $cmd;
		if($^O =~ /mswin/i){
			$cmd = "copy $packagename.$ext \\\\$image_server\\DB_REL\\$MAJ$MIN$COR$BUILD\\$ospath\\$packagename.$ext";
		}
		else{
			$cmd = "rem cp $packagename.$ext $image_server:d:/DB_REL/$MAJ$MIN$COR$BUILD/$ospath/$packagename.$ext";
		}
		do_cmd($cmd);
		$? == 0 || err("cannot copy archive to CD-Images: $errtext");
	}
	close(LOG);
	exit 0;
}


1;






