#! /usr/bin/perl
#
# $Header: //sapdb/TOOLSRC/develop/sys/src/BuildPackage/Distrib.pm#13 $
# $DateTime: 2002/11/26 13:47:50 $
# $Change: 31740 $
#
# Desc:	- generate distribution packages with software components from make machines
#		
#
#
#    ========== 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::Distrib;

use BuildPackage::Vars;
use BuildPackage::Tools;
use BuildPackage::Hosts;

use Getopt::Long;
use WinLink;
use Cwd;


sub err{
	my ($errtext) = @_;
	die($errtext);
}



BuildPackage::Tools::setMsgHandler(sub {print $_[0] if($opt_verbose);});
BuildPackage::Tools::setErrMsgHandler(sub {die $_[0];});



my %replacements;

my $cwd = cwd();
my $dest_dir = $cwd;

my $ftp;



sub do_opt_check{
	my $rc = 1;
	unless(defined $opt_profile || $opt_profile !~ /\S/){
		print "\nno profile\n\n";
		$rc = 0;
	}

	
	if(defined $opt_format){
		unless($opt_format =~ /^TGZ$|^ZIP$|^SAR$|^RPM$/i){
			print "\n-format: wrong usage\n\n";
			$rc = 0;
		}
		if($opt_format =~ /^RPM$/i){
			if(defined $opt_os){
				unless ($opt_os =~ /^LINUX/){
					print "\n-format: wrong usage - RPM is for linux only\n\n";
					$rc = 0;
				}

			}
			elsif($^O !~ /linux/i){
				print "\n-format: wrong usage - RPM is for linux only\n\n";
				$rc = 0;
			}
			if($opt_os_style){
				print "\n-os_style: wrong usage - RPM has no special open source style\n\n";
				$rc = 0;
			}
		}
	}
		
	if(defined $opt_state){
		unless($opt_state =~ /^DEV$|^COR$/){
			print "\n-state: wrong usage\n\n";
			$rc = 0;
		}
	}
	
	if(defined $opt_version){
		if($opt_version !~ /^7[234]0[0-5][012][0-9]$|^7[234]0[0-5]$/){
			print "\n-version: wrong usage\n\n";
			$rc = 0;
		}
		else{
			if(length($opt_version) == 4){
				unless($opt_state =~ /^DEV$|^COR$/){
					print "\n-version: wrong usage:  need -state COR|DEV\n\n";
					$rc = 0;
				}
			}
			else{
				if($opt_state =~ /\S/){
					print "\n-state: wrong usage: -version with buildlevel inside don\'t want -state, it\'s always RAMP\n\n";
					$rc = 0;
				}
			}
		}
	
	}

	if(defined $opt_state){
		unless($opt_version =~ /^7[234]0[0-5][012][0-9]$|^7[234]0[0-5]$/){
			print "\n-lcstate: wrong usage\n\n";
			$rc = 0;
		}
	}

	if(defined $opt_dir){
		if(-d $opt_dir){
			$dest_dir = $opt_dir;
			if(($^O =~ /mswin/i && $dest_dir !~ /^[a-z]:/i) || ($^O !~ /mswin/i && $dest_dir !~ /^\//)){
				$dest_dir = $cwd.'/'.$opt_dir;
			}
			$dest_dir =~ s/\\/\//g;			
		}
		else{
			print "\n-dir $opt_dir: wrong usage - no such directory\n\n";
			$rc = 0;
		}

	}

	return $rc;
}



$tmp_dir = '/tmp';
exists $ENV{'TMP'} and -d $ENV{'TMP'} and $tmp_dir = $ENV{'TMP'}; 
$tmp_dir = (exists $ENV{TEMP} ? $ENV{TEMP} : $ENV{TMP}) if $^O =~ /mswin/i;


sub loadModule{
	my ($module,$path,$remote_host,$replacements) = @_;
	
	if ($remote_host){
		my ($modpath,$modfile) = ($module =~ /(.*)::([^:]+)$/);
		$modfile .= '.pm';
		#print ">>>> modfile = $modfile \n";
		$modpath =~ s/::$//;
		$modpath =~ s/::/\//g;

		#
		# create local tmp_path
		#
		makedir("$tmp_dir/$modpath",0775) or die("cannot create \"$tmp_dir/modpath\"\n");
		
		
		#
		# copy module into local tmp_path
		#
		
		remoteGet($ftp,$path."/$modpath/$modfile","$tmp_dir/$modpath/$modfile");
		
		if(defined $replacements && ref($replacements) eq 'HASH'){
			open(FD,"$tmp_dir/$modpath/$modfile") or die ("cannot open file $tmp_dir/$modpath/$modfile: $!\n");
			my @buf;
			while(<FD>){ chomp; push @buf,$_;}
			close(FD);
			open(FD,">$tmp_dir/$modpath/$modfile") or die ("cannot create file $tmp_dir/$modpath/$modfile: $!\n");
			foreach my $line (@buf){
				foreach my $repl (keys(%$replacements)){
					my $with = $replacements->{$repl};
					$line =~ s/$repl/$with/g;
				}
				print FD $line."\n";
			}
			close(FD);	
		}
		
		loadModule($module,$tmp_dir);	
	}
	else{
		-d $path or die("loadPackDefs(): directory \"$path\" not found\n");
		my $module_file = $module.'.pm';
		$module_file =~ s/::/\//g;
		-f "$path/$module_file" or die("loadPackDefs(): module \"$module\" not found\n");
		$path =~ s/\//\\/g if ($CUR_OS =~ /WIN/); 
		$path = 'd:'.$path if ($CUR_OS =~ /WIN/ && ! $path =~ /^[a-z]:/i); 
		local @INC = ($path);
		eval "require $module";
		die($@) if $@;
		import $module;
		foreach my $key (keys(%profiles)){
			$opt_verbose && print ">>>>>>$key\n";
		} 
	}
	return 1;
}




sub getPoolPath{
	my $pool_path = '';
	my $buildselect = ($opt_buildselect ? $opt_buildselect : 'LastBuild');
	if(!$opt_os){
		#
		# local
		#
		my $mode = ($CUR_OS =~ /64/ ? '64' : '32');	
		my $state = $LC_STATE;
		$state = 'DEV' unless($state);
		$opt_version =~ s/\d\d$// if($state =~ /^DEV$|^COR$/ and length($opt_version) == 6);
		if($opt_version){
			if($opt_old){
				$pool_path = $SAPDB_POOL_ROOT; 
				$pool_path .= "/SDBC_${opt_version}_${mode}_${state}";
			}
			else{
				$pool_path = $LC_POOL_ROOT; 
				$pool_path .= "/LC_${opt_version}_${mode}_${state}";
			}
		}
		else{
			# version of dev environment
			if($opt_old){
				$pool_path = $SAPDB_POOL_DIR;
			}
			else{
				$pool_path = $LC_POOL_DIR;
			}

		}
		
		-e "$pool_path/$buildselect" or die("cannot find pool slot \"$pool_path/$buildselect\"\n");		
		-d "$pool_path/$buildselect" and return "$pool_path/$buildselect";
		return "$pool_path/".(readLink ("$pool_path/$buildselect")) if($CUR_OS =~ /WIN/ && -f "$pool_path/$buildselect");
	
	}
	elsif($opt_version){
		#
		# remote 
		#
		my $mode = ($opt_os =~ /64/ ? '64' : '32');	
		my $state = (length($opt_version) == 6 ? 'RAMP' : $opt_state);
		my ($version) = ($opt_version =~ /^(\d{4})/);
		exists $HOSTS{$version} or die("no host defined for version $version\n");
		exists ${%{$HOSTS{$version}}}{$opt_os}  or die("no host defined for os $opt_os\n");
		my $host = ${%{$HOSTS{$version}}}{$opt_os}->{'name'};
		if($opt_old){
			$pool_path = $SAPDB_POOL_ROOT."/SDBC_${opt_version}_${mode}_${state}";
		}
		else{
			$pool_path = $LC_POOL_ROOT."/LC_${opt_version}_${mode}_${state}";
		}
		$opt_verbose && print ">>>>>path = $pool_path\n";
		$ftp = ftp_connect($host);  
		my %entries = remoteLs($ftp,$pool_path);
		exists $entries{$buildselect} or err("buildselect \"$buildselect\" not found\n"); 
		if($entries{$buildselect}->{'type'} eq 'd'){
			$opt_verbose && print ">>>>> final pool path = $pool_path/$buildselect\n";
			return ($pool_path."/$buildselect",$host);
		}
		elsif($entries{$buildselect}->{'type'} eq 'l'){
			exists $entries{$entries{$buildselect}->{'dest'}} or 
				err("buildselect \"$buildselect\"not found: cannot resolve link\n");
			if($entries{$entries{$buildselect}->{'dest'}}->{'type'} eq 'd'){
				$opt_verbose && print ">>>>> final pool path = $pool_path/".$entries{$buildselect}->{'dest'}."\n";
				return ($pool_path.'/'.$entries{$buildselect}->{'dest'},$host);
			}
			else{
				err("resolved link is no directory\n");
			}
			 
		}
		else{
			# windows
			remoteGet($ftp,$pool_path.'/'.$buildselect,$tmp_dir.'/'.$buildselect);
			my $resolved = readLink($tmp_dir.'/'.$buildselect);
			exists $entries{$resolved} or err(" resolved buildselect \"$resolved\" not found\n"); 
			if($entries{$resolved}->{'type'} eq 'd'){
				$opt_verbose && print ">>>>> final pool path = $pool_path/$resolved\n";
				return ($pool_path.'/'.$resolved,$host);
			}
			else{
				err("resolved link \"$resolved\" is no directory\n");
			}
		}
		
		
		#remoteLs(p26325,'/CD-Images/db_rel');
		
		die("remote pool: not implemented yet\n");
		
	}
	else{
		die("cannot get pool path: version not known\n");
	}
}


sub getArchiveBuildNum{
	my ($archive) = @_;
	my $local_dir = 'getBuildNum'; 
	my $build;
	my $mycwd = cwd();
	chdir($tmp_dir);
	makedir($local_dir,0775);
	chdir($local_dir);
	my $cmd = ($^O =~ /mswin|linux/i ? 'tar' : 'gtar' )." -xvpzf $archive PACKAGEDATA";
	if($^O =~ /mswin/i){
		$cmd =~ s/[a-z]://i;
		$cmd =~ s/\//\\/g;
		#$cmd =~ s/\\/\\\\/g;
	}
	do_cmd($cmd);	
	my $version;
	open(FD,'PACKAGEDATA') or die("cannot open PACKAGEDATA\n");
	while(<FD>){
		/^SOFTWARE_VERSION\s*=\s*"(.+)"/ and $version = $1 and last;
	}
	close(FD);
	if(defined $version){
		($build) = ($version =~ /(\d\d)$/); 
	}
	else{
		die("cannot get build\n");
	}
	chdir($tmp_dir);
	deltree($local_dir);
	chdir($mycwd);
	return $build;
}



sub getRPMs{
	my ($src_dir,$files,$remote_host) = @_;
	
	my $buildroot = "$tmp_dir/buildroot";
	-d $buildroot and deltree($buildroot);
	makedir("$buildroot/".$inner_subdir,0775) or die("cannot create directory \"$inner_sub_dir\": $!\n");
		
	if($remote_host){
		my %entries = remoteLs($ftp,$src_dir);
		print "get files...\n";
		my @rpm_files = ();
		foreach my $file (@$files){
			my $pattern = $file;
			$pattern =~ s/\//\\\//g;
			foreach my $repl (keys(%replacements)){
				$pattern =~ s/$repl/$replacements{$repl}/g;
			}
			$pattern =~ s/%build/\\d+/g;

			my $found_rpm = 0;
			foreach my $found_file (keys(%entries)){
				if($found_file =~ /^$pattern$/){
					$found_rpm = 1;
					$entries{$found_file}->{'type'} eq 'f' or err("RPM $found_file isn\'t a file\n");
					push @rpm_files,$found_file;
					last;
				}
			}
			unless($found_rpm){
				err("no matching RPM found: \"$file\"\n");
			}
		}	

		foreach my $rpm (@rpm_files){
			print "$rpm\n";
			remoteGet($ftp,"$src_dir/$rpm","$buildroot/$rpm",1);
			unless($^O =~ /mswin/i){
				if($entries{$rpm}->{'mode'}){
					chmod($entries{$rpm}->{'mode'},"$buildroot/$rpm");
				}
			}
			utime($entries{$rpm}->{'time'},$entries{$rpm}->{'time'},"$buildroot/$rpm");			
			copy("$buildroot/$rpm",$dest_dir,1);
		}
		ftp_release($ftp);
		deltree($buildroot);
	}
	else{
		err("RPMs local not yet implemeted\n");
	}
	return 1;
}



sub packArchive{
	my ($src_dir,$arfiles,$profile,$remote_host) = @_;
	
	my $inner_subdir;
	my $archive_name;
	
	if($profile =~ /^all$/i){
		$inner_subdir = $profile_data{'Server'}->{'inner_subdir_tmpl'};
		$inner_subdir =~ s/server-/all-/;
		$archive_name = $profile_data{'Server'}->{'archive_name_tmpl'};
	}
	else{
		$inner_subdir = $profile_data{$profile}->{'inner_subdir_tmpl'};
		$archive_name = $profile_data{$profile}->{'archive_name_tmpl'};
	}

	
	foreach my $pattern (keys(%replacements)){
		$inner_subdir =~ s/$pattern/$replacements{$pattern}/g;
		$archive_name =~ s/$pattern/$replacements{$pattern}/g;
	}	
	
	my $buildroot = "$tmp_dir/buildroot";
	-d $buildroot and deltree($buildroot);
	makedir("$buildroot/".$inner_subdir,0775) or die("cannot create directory \"$inner_sub_dir\": $!\n");
			
	
	# get files
	if($remote_host){
		#remote 
		my %entries = remoteLs($ftp,$src_dir);
		my $PCR_inside = 0;
		print "get files...\n";
		foreach my $file (@$arfiles){
			$file =~ /^PCR\d{4}\.TGZ$/ and $PCR_inside = 1 and $mainPCR = $file;
			exists $entries{$file} or die("$file not found in $remote_host:/$src_dir \n");
			remoteGet($ftp,"$src_dir/$file","$buildroot/$inner_subdir/$file",1);
			unless($^O =~ /mswin/i){
				if($entries{$file}->{'mode'}){
					chmod($entries{$file}->{'mode'},"$buildroot/$inner_subdir/$file");
				}
			}
			utime($entries{$file}->{'time'},$entries{$file}->{'time'},"$buildroot/$inner_subdir/$file");			
			#copy("$src_dir/$file","$buildroot/".$inner_subdir,1);					
		}	
		
		my @PCRs;
		if($PCR_inside and  $profile !~ /Develop|Precompiler|SDK/){
			@PCRs = grep { /^PCR\d{4}\.TGZ$/ && not /$mainPCR/ && $entry{$_}->{'type'} eq 'f'} keys(%entries);
		}
		foreach my $pcr (@PCRs){
			remoteGet($ftp,"$src_dir/$pcr","$buildroot/$inner_subdir/$pcr",1);
			unless($^O =~ /mswin/i){
				if($entries{$pcr}->{'mode'}){
					chmod($entries{$pcr}->{'mode'},"$buildroot/$inner_subdir/$pcr");
				}
			}
			utime($entries{$pcr}->{'time'},$entries{$pcr}->{'time'},"$buildroot/$inner_subdir/$pcr");			
		}
		ftp_release($ftp);
		my $build = getArchiveBuildNum("$buildroot/$inner_subdir/SAPDBBAS.TGZ");
		my $new_inner_subdir = $inner_subdir;
		$archive_name =~ s/%BUILD/$build/g;
		$build =~ s/^0*//;
		$build = 0 unless($build =~ /\S/);
		$new_inner_subdir =~ s/%build/$build/g;
		rename("$buildroot/$inner_subdir","$buildroot/$new_inner_subdir");	
		$inner_subdir = $new_inner_subdir;
	}
	else{
		#local
		my $PCR_inside = 0;
		my $mainPCR;
		print "get files...\n";
		foreach my $file (@$arfiles){
			$file =~ /^PCR\d{4}\.TGZ$/ and $PCR_inside = 1 and $mainPCR = $file;
			copy("$src_dir/$file","$buildroot/".$inner_subdir,1);					
		}
		my @PCRs;
		if($PCR_inside){
			opendir(DH,$src_dir) or die ("cannot open directory \"$src_dir\"\n");
			@PCRs = grep { /^PCR\d{4}\.TGZ$/ && not /$mainPCR/ && -f "$src_dir/$_" } readdir(DH);
			closedir(DH);
		}
		unless (exists $replacements{'%BUILD'}){
			my $build = getArchiveBuildNum("$buildroot/$inner_subdir/SAPDBBAS.TGZ");
			my $new_inner_subdir = $inner_subdir;
			$archive_name =~ s/%BUILD/$build/g;
			$build =~ s/^0*//;
			$build = 0 unless($build =~ /\S/);
			$new_inner_subdir =~ s/%build/$build/g;
			rename("$buildroot/$inner_subdir","$buildroot/$new_inner_subdir");	
			$inner_subdir = $new_inner_subdir;
		}
		foreach my $pcr (@PCRs){
			copy("$src_dir/$pcr","$buildroot/".$inner_subdir,1);					
		}
			
	}
	chdir($buildroot);
	print "pack distribution archive...\n";
	
	my $ar_ext = '.SAR';

	if($opt_os_style){
		$archive_name = $inner_subdir;
		$ar_ext =~ tr/[A-Z]/[a-z]/
	}

	my $cmd = "SAPCAR -cvf $dest_dir/${archive_name}${ar_ext} $inner_subdir";
	if($opt_format =~ /^tgz$/i){
		if($remote_host && $^O =~ /mswin/i && $opt_os !~ /WIN/){
			$ar_ext = '.TAR';
			$ar_ext =~ tr/[A-Z]/[a-z]/ if ($opt_os_style);
			$cmd = 'tar -cvpf '."${archive_name}${ar_ext} $inner_subdir";
		
		}
		else{
			$ar_ext = '.TGZ';
			$ar_ext =~ tr/[A-Z]/[a-z]/ if ($opt_os_style);
			$cmd = (($^O =~ /mswin|linux/i) ? 'tar' : 'gtar').
				' -cvpzf '.($^O =~ /mswin/i ? '' : "$dest_dir/")."${archive_name}${ar_ext} $inner_subdir";
		}
	}
	elsif($opt_format =~ /^zip$/i){
		$ar_ext = '.ZIP';
		$ar_ext =~ tr/[A-Z]/[a-z]/ if ($opt_os_style);
		$cmd = undef;
		if(($opt_os and $opt_os !~ /WIN/) or (not $opt_os and $^O !~ /mswin/i)){
			print STDERR "WRN: pkzip isn\'t able to restore unix file permissons\n";
			print STDERR "WRN: please use another archive format (sar,tgz) for unix OSs\n";
		}
		require BuildPackage::PackZip;
		BuildPackage::PackZip::packzip("$dest_dir/${archive_name}${ar_ext}",'.',$inner_subdir);			
	}
	$cmd =~ s/\//\\\\/g if $^O =~ /mswin/i;
	do_cmd($cmd) if $cmd;
	
	#
	# add execute permissions for unix installer files inside a windows packed sar archive
	#
	
	if($remote_host && $^O =~ /mswin/i && $opt_os !~ /WIN/ && $cmd =~ /^SAPCAR/){
		require BuildPackage::PatchSar;
		print "change permissions of installer inside sar archive...\n";
		my $sarpatcher = BuildPackage::PatchSar->new("$dest_dir/${archive_name}${ar_ext}");
		$sarpatcher->patchPermissions({'*/SDBINST' => 0775,'*/SDBRUN' => 0775,'*/SDBUPD' => 0775});  
	}
	elsif($remote_host && $^O =~ /mswin/i && $opt_os !~ /WIN/ && $cmd =~ /^tar/){
		require BuildPackage::PatchTar;
		print "change permissions of installer inside tar archive...\n";
		my $tarpatcher = BuildPackage::PatchTar->new("${archive_name}${ar_ext}");
		$tarpatcher->patchPermissions({'*/SDBINST' => 0775,'*/SDBRUN' => 0775,'*/SDBUPD' => 0775});  
		my $new_ext = $opt_os_style ? '.tgz' : '.TGZ';
		$cmd = 'gzip -c -9 '."${archive_name}${ar_ext}".' >'.${archive_name}.$new_ext;
		${ar_ext} = $new_ext;
		do_cmd($cmd);
	}


	if ($^O =~ /mswin/i && $opt_format =~ /^tgz$/i){
		copy("${archive_name}${ar_ext}",$dest_dir,1);
	}	
	chdir($cwd);
	print "archive $dest_dir/${archive_name}${ar_ext} successfully packed\n";
	deltree($buildroot);
}

$pid_file;


sub main{
	local @ARGV = @_;
	my %optCtrl = (
		'h' => \$opt_h,
		'help' => \$opt_h,
		'profile=s' => \$opt_profile,
		'pool=s' => \$opt_pool,
		'format=s' => \$opt_format,
		'os=s' => \$opt_os,
		'os_style' => \$opt_os_style,
		'old' => \$opt_old,
		'version=n' => \$opt_version,
		'lca_version=s' => \$opt_lca_version,
		'buildselect=n' => \$opt_buildselect,
		'dir=s' => \$opt_dir,
		'state=s' => \$opt_state,
		'verbose' => \$opt_verbose
	);
	
	my $usage = " [-h|--help] -profile <profile>\n".
				"\t[-format SAR|TGZ|ZIP|RPM] [-os <operating system>]\n".
				"\t-version <version> [-state COR|DEV]\n".
				"\t[-buildselect <000..999>|<link name>]\n".
				"\t[-verbose] [-dir <destination directory>]\n".
				"\t[-os_style]\n";

	
	if(!GetOptions(%optCtrl) || $opt_h ||  ! do_opt_check()){
		print "usage: packdistrib $usage\n"; 
		exit ($opt_h ? 0 : 1);
	}
	
	if($opt_verbose){
		$BuildPackage::Tools::DEBUG = 1;
	}

	$tmp_dir = $tmp_dir."/packdistrib";
	my $tmp_dir_base = $tmp_dir;

	my $count;
	while(1){
		$tmp_dir = $tmp_dir_base.$count;
		$count = (defined $count ? ($count + 1) : 0);
		if (-d $tmp_dir){
			my $pid_file = $tmp_dir.'/pid'; 
			if(-f $pid_file){
				open(FH,$pid_file) or next;
				my $pid;
				while(<FH>){
					chomp;
					$pid = $_;
				}
				close(FH);
				if($^O =~ /mswin/i || kill (0 => $pid)){
					if((time - (stat($pid_file))[9]) >  86400){
						# more than one day 
						last;
					}
				}	
			}
			else{
				last;
			} 
		}
		else{
			makedir($tmp_dir,0775) or die("cannot create directory $tmp_dir\n");
			last;
		}
	}
	
	$opt_verbose && print ">>>>>tmp dir = $tmp_dir\n";

	open(FH,'>'.$tmp_dir.'/pid') or die ("cannot create pid file in $tmp_dir\n"); 
	print FH "$$\n";
	close(FH);
	$pid_file = $tmp_dir.'/pid';

	my ($pool_path,$host) = getPoolPath();
	
	unless($opt_old){
		$pool_path .= "/$SAPDB_COMPONENTS_DIR";
	}
	
	print "load profile definition module...\n";
	
	my ($version) = ($opt_version =~ /^(\d{4})/);	
	
	loadModule('BuildPackage::PackDefs',$pool_path,$host,($version =~ /^\d{4}$/ ? {'\$RUNTIME_VERSION' => $version,
		'\$MAJ\$MIN\$COR' => $version, '\$MAJ\s==\s7\s\&\&\s\$MIN\s>\s4' => 1} : undef));	
	unless($opt_profile =~ /^all$/i or exists $profiles{$opt_profile}){
		die("no profile \"$opt_profile\" found\n");
	} 
	
	
	if($opt_os){
		exists $OSS{$opt_os} or die("cannot find \"$opt_os\" in \%OSS\n");	
		%replacements = (
			'%OS' => $OSS{$opt_os}->{name},
			'%ARCH' => $OSS{$opt_os}->{arch},
			'%BIT' => $OSS{$opt_os}->{bit}
		);
	}
	else{
		exists $OSS{$CUR_OS} or die("cannot find \"$opt_os\" in \%OSS\n");	
		%replacements = (
			'%OS' => $OSS{$CUR_OS}->{name},
			'%ARCH' => $OSS{$CUR_OS}->{arch},
			'%BIT' => $OSS{$CUR_OS}->{bit}
		);
	}


	if($opt_version){
		my ($maj,$min,$cor,$build) = ($opt_version =~ /^(\d)(\d)(\d\d)(\d{0,2})$/);		
		$replacements{'%MAJ'} = $maj;
		$replacements{'%MIN'} = $min;
		$replacements{'%COR'} = $cor;
		$cor =~ s/^0*//;
		$cor = 0 unless($cor =~ /\S/);
		$replacements{'%cor'} = $cor;
		if($build =~ /\d\d/){
			$replacements{'%BUILD'} = $build;
			$build =~ s/^0*//;
			$build = 0 unless($build =~ /\S/);
			$replacements{'%build'} = $build;
		}
	}
	else{
		$replacements{'%MAJ'} = $MAJ;
		$replacements{'%MIN'} = $MIN;
		$replacements{'%COR'} = $COR;
		my $cor = $COR;
		$cor =~ s/^0*//;
		$cor = 0 unless($cor =~ /\S/);
		if($LC_STATE eq 'RAMP'){ 
			$replacements{'%BUILD'} = $BUILD;
			my $build = $BUILD;
			$build =~ s/^0*//;
			$build = 0 unless($build =~ /\S/);
			$replacements{'%cor'} = $cor;
			$replacements{'%build'} = $build;
		}
	}

	my @files = ();
	
	print "check profile \"$opt_profile\"...\n";
		
	if($opt_format =~ /^rpm$/i){
		exists $RPM_PROFILES{$opt_profile}  or $opt_profile =~ /^all$/i or die("rpm profile $opt_profile not found\n");
		if($opt_profile =~ /^all$/i){
			@files = values(%ALL_RPMS);
		}
		else{
			foreach my $rpm (@{$RPM_PROFILES{$opt_profile}}){
				push @files,$ALL_RPMS{$rpm};
			}
		}
		getRPMs($pool_path,\@files,$host);		
		print "rpms successfully packed\n";
		exit (0);
	}
	
	
	
	if($opt_profile =~ /^all$/i){
		foreach my $package (@allpackages){
			$package->{'name'} =~ /^LC|^APO/ and next;
			push @files, $package->{'archive'};
			exists $package->{'additional_installer_files'} and push @files,@{$package->{'additional_installer_files'}}; 
		}
	}
	else{
		foreach my $package_of_profile (@{$profiles{$opt_profile}}){
			my $found = 0;
			$package_of_profile =~ /\S/ or next;
			foreach my $package (@allpackages){
					if($package->{'name'} eq $package_of_profile){
					$found = 1;
					push @files, $package->{'archive'};
					exists $package->{'additional_installer_files'} and push @files,@{$package->{'additional_installer_files'}}; 
					last;
				} 
			}
			unless($found){
				die("definition of package \"$package_of_profile\" not found\n");
			}
		}
	}	
	
	push @files,@installer_files;
	
	
	packArchive($pool_path,\@files,$opt_profile,$host);
	deltree($tmp_dir);
	exit 0;
}


1;