#!/usr/bin/perl
# BEGIN_ICS_COPYRIGHT8 ****************************************
#
# Copyright (c) 2015-2020, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#     * Redistributions of source code must retain the above copyright notice,
#       this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above copyright
#       notice, this list of conditions and the following disclaimer in the
#       documentation and/or other materials provided with the distribution.
#     * Neither the name of Intel Corporation nor the names of its contributors
#       may be used to endorse or promote products derived from this software
#       without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# END_ICS_COPYRIGHT8   ****************************************

# [ICS VERSION STRING: unknown]
use strict;
#use Term::ANSIColor;
#use Term::ANSIColor qw(:constants);
#use File::Basename;
#use Math::BigInt;

# =============================================================================
# The functions and constants below assist in using DEB files
my $rpm_check_dependencies = 1;	# can be set to 0 to disable rpm_check_os_prereqs

my $RPM_ARCH=my_tolower("$ARCH");
my $RPM_KERNEL_ARCH = `uname -m`; # typically matches $RPM_ARCH
chomp $RPM_KERNEL_ARCH;

# return array of cmds for verification during init
sub rpm_get_cmds_for_verification()
{
	return ("dpkg", "dpkg-deb", "dpkg-query");
}

sub rpm_to_deb_option_trans($)
{
	my ($options) = shift();

	#Update option is not required for deb, remove it
	$options =~ s/-U//g;
	#Installation despite lacking dependencies should not be necessary on Ubuntu
	$options =~ s/--nodeps/--force-depends/g;

	return $options;
}

# version string for kernel used in RPM filenames uses _ instead of -
sub rpm_tr_os_version($)
{
	my $osver = shift();	# uname -r style output
	$osver =~ s/-generic//;
	$osver =~ s/-/./g;
	return "$osver";
}

# translation from rpm package format to deb one
sub rpm_to_deb_pkg_trans($)
{
	my ($pkg) = shift(); # package name
	return $pkg;
}

# Attribute translation
sub rpm_to_deb_attr_trans($)
{
	my $attr = shift();	# attribute name: such as NAME or VERSION
	if($attr eq 'RELEASE'){
		$attr = 'Version';
	}

	if($attr eq 'NAME'){
		$attr = 'Package';
	}

	if($attr eq 'VERSION'){
		$attr = 'Version';
	}

	if($attr eq 'INSTALLPREFIX'){
		# TODO: no equivalent in dpkg
		$attr = '/usr/mpi';
	}

	return $attr;
}

# query a parameter of RPM tools themselves
sub	rpm_query_param($)
{
	my $param = shift();	# parameter name: such as _mandir, _sysconfdir, _target_cpu
	my $ret = '';

	if($param eq 'arch'){
		$ret = `dpkg --print-architecture`;
	} elsif ($param eq '_mandir'){
		$ret = '/usr/share/man';
	} elsif ($param eq '_sysconfdir'){
		$ret = '/etc';
	} elsif ($param eq 'optflags'){
		return "";
	} else {
		return "";
	}

	chomp $ret;
	return $ret;
}

# query an attribute of the RPM file
sub	rpm_query_attr($$)
{
	my $debfile = shift();	# .deb file
	my $attr = shift();	# attribute name: such as NAME or VERSION

	$attr = rpm_to_deb_attr_trans($attr);

	if ( ! -f "$debfile" ) {
		return "";
	}

	my $query = 'dpkg-deb --showformat=\'${'.$attr.'}\n\' --show '.$debfile.' 2>/dev/null';
	my $val = `$query`;

	return $val;
}

# query an attribute of the installed RPM package
sub	rpm_query_attr_pkg($$)
{
	my $package = shift();	# installed package
	my $attr = shift();	# attribute name: such as NAME or VERSION

	$attr = rpm_to_deb_attr_trans($attr);
	$package = rpm_to_deb_pkg_trans($package);

	my $val = `dpkg-query --showformat='\${$attr}\n' --show $package 2>/dev/null`;

	return $val; 
}

# get name of deb package
sub rpm_query_name($)
{
	my $debfile = shift();	# .deb file
	return rpm_query_attr($debfile, "Package");
}

# return NAME-VERSION-RELEASE.ARCH
sub rpm_query_full_name($)
{
	my $debfile = shift();	# .deb file

	if ( ! -f "$debfile" ) {
		return "";
	}
	my $var = `dpkg-deb --showformat='[\${Package}-\${Version}.\${Architecture}]' --show $debfile 2>/dev/null`;
	return $var;
}

# get list of package debs installed
# the list could include multiple versions and/or multiple architectures
# and/or multiple kernel releases
# all entries in returned list are complete package names in the form:
#	NAME-VERSION-RELEASE.ARCH
sub rpms_installed_pkg($$)
{
	my $package=shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
											# "any"- checks if any variation of package is installed
	my @lines=();
	my $cpu;

	$package = rpm_to_deb_pkg_trans($package);

	$cpu = rpm_get_cpu_arch($mode);
	my $cmd = 'dpkg-query --showformat=\'${Package}:${Architecture}\' --show '.$package.' 2>/dev/null\n';
	if ( "$mode" eq "any" ) {
		DebugPrint($cmd."|");
		open(debs, $cmd."|");
	} elsif ("$mode" eq "user" || "$mode" eq "firmware") {
		DebugPrint($cmd."|grep -E '\.$cpu\$' 2>/dev/null\n");
		open(debs, $cmd."|grep -E '\.$cpu\$' 2>/dev/null|");
	} else {
		# $mode is kernel rev, verify proper kernel version is installed
		# for kernel packages, RELEASE is kernel rev
		my $release = rpm_tr_os_version($mode);
		DebugPrint($cmd."|grep -E '-$release\.$cpu\$' 2>/dev/null\n");
		open(debs, $cmd."|grep -E '-$release\.$cpu\$' 2>/dev/null|");
	}
	@lines=<debs>;
	close(debs);
	if ( $? != 0) {
		# query command failed, package must not be installed
		@lines=();
	}
	chomp(@lines);
	DebugPrint("package $package $mode: installed: @lines\n");
	return @lines;
}

# get list of package debs installed
# the list could include multiple versions and/or multiple architectures
# and/or multiple kernel releases
# all entries in returned list are complete package names in the form:
#	NAME:ARCH
sub rpms_variations_installed_pkg($$)
{
	my $package=shift();
	my $mode = shift();

	my @result=();

	@result = ( @result, rpms_installed_pkg($package, $mode) );
	return @result;
}

sub rpm_query_all($$)
{
	my $package = shift();
	my $filter = shift();

	$package = rpm_to_deb_pkg_trans($package);

	my $res=`dpkg --get-selections 2>/dev/null |grep -v '\sdeinstall\s'|grep -i '$package'|grep '$filter'`;
	$res=~s/\n/ /g;
	return $res;
}

# determine if rpm parameters will allow srpms to build debuginfo rpms
sub rpm_will_build_debuginfo()
{

}

sub rpm_query_version_release($)
{
	my $debfile = shift();	# .deb file
	return rpm_query_attr($debfile, "VERSION");
}

sub rpm_query_release_only_file($)
{
	my $debfile = shift();
	my $ver_and_rel = rpm_query_version_release($debfile);
	my ($ver, $rel) = split /-/, $ver_and_rel;
	return $rel;
}

# get VERSION-RELEASE of installed RPM package
sub rpm_query_version_release_pkg($)
{
	my $package = shift();	# installed package
	return rpm_query_attr_pkg($package, "VERSION");
}

sub rpm_query_release_only_pkg($)
{
	my $package = shift();
	my $ver_and_rel = rpm_query_version_release_pkg($package);
	my ($ver, $rel) = split /-/, $ver_and_rel;
	return $rel;
}

sub rpm_get_cpu_arch($)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	return rpm_query_param("arch");
}

my $last_checked;	# last checked for in rpm_is_installed
sub rpm_is_installed($$)
{
	my $package = shift();	# package name
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $rc;
	my $cpu;

	$package = rpm_to_deb_pkg_trans($package);

	if ($user_space_only && "$mode" ne "user" && "$mode" ne "any") {
		return 1;
	}

	$cpu = rpm_get_cpu_arch($mode);
	if ("$mode" eq "any" ) {
		# any variation is ok
		my $cmd = "dpkg-query --show '$package' >/dev/null 2>&1";
		DebugPrint $cmd."\n";
		$rc = system($cmd);
		$last_checked = "any variation";
	} elsif ("$mode" eq "user" || "$mode" eq "firmware") {
		# verify $cpu version or any is installed
		my $cmd = "dpkg -l '$package' 2>/dev/null | grep -E '^ii' 2>/dev/null|grep -E '^$cpu\$|' >/dev/null 2>&1";
		DebugPrint $cmd."\n";
		$rc = system $cmd;
		$last_checked = "for $mode $cpu or noarch";
	} else {
		# $mode is kernel rev, verify proper kernel version is installed
		# for kernel packages, RELEASE is kernel rev
		my $release = rpm_tr_os_version($mode);
		my $showformat = q('${db:Status-Abbrev} ${binary:Package} ${Version}');
		my $cmd = "dpkg-query --showformat=$showformat --show $package";
		$cmd .= " | grep -E '^ii' >/dev/null 2>&1";
		$cmd .= " | grep -E '$release' >/dev/null 2>&1";
		DebugPrint $cmd."\n";
		$rc = system $cmd;
		$last_checked = "for kernel $release";
	}
	DebugPrint("Checked if $package $mode is installed: ".(($rc==0)?"yes":"no")."\n");
	return 0 == $rc;
}

sub rpm_is_installed_list($@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- verifies any variation of package is installed
	my @package_list = @_;	# package names

	foreach my $package ( @package_list )
	{
		if ( !  rpm_is_installed($package, $mode) ) {
			return 0;
		}
	}
	return 1
}

# return 0 on success, number of errors otherwise
sub rpm_check_os_prereqs_internal($$@)
{
	my $mode = shift();	# default mode
	my $message = shift();
	my @package_list = @_;	# package names
	my $err=0;
	
	if ( ! $rpm_check_dependencies ) {
		return 0;
	}
	# Check installation requirements
	DebugPrint "Checking prereqs $message: @package_list\n";
	for my $package_info ( @package_list )
	{
		# expand any alias in package_info
		my $full_package_info="";
		my @alternatives = (split ('\|',$package_info));
		for my $altpackage_info ( @alternatives )
		{
			my ($package, $details) = (split (' ',$altpackage_info,2));
			if ($details ne "") {
				$details=" $details";
			}
			if ( "$full_package_info" ne "" ) {
				$full_package_info = "$full_package_info|";
			}

			# expand "g77" alias for various fortran compilers
			# and "libgfortran" alias for various fortran library
			if ("$package" eq "g77" ) {
				# on Ubuntu 17.04: gfortran
				$full_package_info = "${full_package_info}gfortran$details";
			} elsif ("$package" eq "libgfortran") {
				# on Ubuntu 17.04: libgfortran
				$full_package_info = "${full_package_info}libgfortran$details";
			} else {
				$full_package_info = "${full_package_info}$altpackage_info";
			}
		}

		# now process the expanded list of alternatives
		DebugPrint "Checking prereq: $full_package_info\n";
		my $errmessage="";
		@alternatives = (split ('\|',$full_package_info));
		for my $altpackage_info ( @alternatives )
		{
			DebugPrint "Checking prereq: $altpackage_info\n";
			my ($package, $version, $pkgmode) = (split (' ',$altpackage_info));
			if ("$pkgmode" eq "") {
				$pkgmode = $mode;
			}

			$package = rpm_to_deb_pkg_trans($package);
			if (! rpm_is_installed($package, $pkgmode)) {
				if ( $errmessage ne "") {
					$errmessage="$errmessage\n OR ";
				}
				$errmessage = "$errmessage$package ($last_checked)";
			} else {
				$errmessage="";
				last;
			}
		}
		if ( $errmessage ne "" ) {
			if (scalar(@alternatives) > 1) {
				$errmessage="$errmessage\n";
			}
			NormalPrint("$errmessage is required$message\n");
			$err++;
		}
	}
	return $err;
}

sub rpm_check_os_prereqs($$)
{
	no strict 'refs';
	my $comp = shift();
	my $mode = shift();
	my $list_name;
	my $array_ref;
	my @rpm_list = {};
	my $prereq_check = 0;

	if ( ! $rpm_check_dependencies ) {
		return 0;
	}

	$list_name=$comp."_prereq";
	$array_ref = $comp_prereq_hash{$list_name};
	#checking if prereq array exists
	#it assumed that it has no prereqs it array does not exist
	if ( $array_ref ) {
		@rpm_list = @{ $array_ref };
	}
	else{
		return 0;
	}

	#checking whether each entry in rpm_list is installed
	DebugPrint "Checking prereqs for $comp\n";
	foreach (@rpm_list){
		DebugPrint "Checking installation of $_\n";
		#Don't check dependencies for kernel PKGS if their installation is skipped
		if($user_space_only == 1){
			if( "$_" =~ /kernel/ || "$_" =~ /kmod/ || "$_" eq "pciutils" ) {
				DebugPrint("Skipping check for $_ \n");
				next;
			}
		}
		if(!rpm_is_installed($_, $mode)){
			NormalPrint("--> $comp requires $_ \n");
			$prereq_check = 1;
		}
	}

	return $prereq_check;
}

sub rpm_check_build_os_prereqs($$@)
{
	my $mode = shift();
	my $build_info = shift();
	my @package_list = @_;	# package names
	return rpm_check_os_prereqs_internal($mode, " to build $build_info", @package_list);
}

# uninstall all packages which match package partial name and filter
# returns 0 on sucess (or package not installed), != 0 on failure
sub rpm_uninstall_matches($$$;$)
{
	my $name = shift();	# for use only in log messages
	my $package = shift();	# part of package name
	my $filter = shift();	# any additional grep filter
	my $options = shift();	# additional rpm command options

	$options = rpm_to_deb_option_trans($options);
	my $rpms = rpm_query_all("$package", "$filter");

	if ( "$rpms" ne "" ) {
		LogPrint "uninstalling $name: dpkg -r $options $rpms\n";
		my $out =`dpkg -r $options $rpms 2>&1`;
		my $rc=$?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
		return $rc;
	} else {
		return 0;
	}
}

sub rpm_run_install($$$)
{
	my $debfile = shift();	# .rpm file
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	my $options = shift();	# additional rpm command options

	$options = rpm_to_deb_option_trans($options);


	if ($user_space_only && "$mode" ne "user" && "$mode" ne "any") {
		return;
	}

	if ( ! -e $debfile ) {
		NormalPrint "Not Found: $debfile $mode\n";
		return;
	}

	my $package = rpm_query_name($debfile);
	my $fullname = rpm_query_full_name($debfile);
	my $out;

	NormalPrint "installing ${fullname}...\n";

	my $cmd = "dpkg --force-confnew -i $options $debfile";
	LogPrint $cmd."\n";
	$out=`$cmd 2>&1`;
	if ( $? == 0 ) {
		NormalPrint("$out");
	} else {
		NormalPrint("ERROR - Failed to install $debfile\n");
		NormalPrint("$out");
		$exit_code = 1;
		HitKeyCont;
	}
}

# returns 0 on sucess (or package not installed), != 0 on failure
# uninstalls all variations of given package
sub rpm_uninstall($$$$)
{
	my $package = shift();	# package name
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $options = shift();	# additional rpm command options
	my $verbosity = shift();	# verbose or silent
	my @fullnames = rpms_variations_installed_pkg($package, $mode); # already adjusts mode
	$options = rpm_to_deb_option_trans($options);
	my $rc = 0;

	foreach my $fullname (@fullnames) {
		if ( "$verbosity" ne "silent" ) {
			print "Uninstalling ${fullname}...\n";
		}
		my $cmd = "dpkg -r $options $fullname";
		LogPrint $cmd."\n";
		my $out=`$cmd 2>&1`;
		$rc |= $?;
		NormalPrint("$out");
		if ($rc != 0) {
			$exit_code = 1;
		}
	}
	return $rc;
}

# resolve rpm package filename for $mode
# package_path is a glob style absolute or relative path to the package
# including the package name, but excluding package version, architecture and
# .rpm suffix
sub rpm_resolve($$)
{
	my $debpath = shift();
	my $mode = shift();
	my $debfile;
	my $cpu;

	$debpath = rpm_to_deb_pkg_trans($debpath);
	
	$cpu = rpm_get_cpu_arch($mode);

	if ( "$mode" eq "user" || "$mode" eq "firmware" || "$mode" eq "any" ) {
		DebugPrint("Checking for User Deb: ${debpath}_*-*_${cpu}.deb\n");
		$debfile = file_glob("${debpath}_*-*_${cpu}.deb");
		if ( "$debfile" eq "" || ! -e "$debfile" ) {
			DebugPrint("Checking for User Deb: ${debpath}_*-*_all.deb\n");
			$debfile = file_glob("${debpath}_*-*_all.deb");
		}
	} else {
		my $kernel_version = rpm_tr_os_version($mode);
		$debfile = file_glob("${debpath}_${kernel_version}*_${cpu}.deb");
	}

	VerbosePrint("Resolved $debpath $mode: $debfile\n");
	return $debfile;
}

sub rpm_exists($$)
{
	my $debpath = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- any variation found
	my $debfile;

	$debfile = rpm_resolve("$debpath", $mode);
	return ("$debfile" ne "" && -e "$debfile")
}

sub rpm_install_with_options($$$)
{
	my $debpath = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
											# "any"- will install any variation found
	my $options = shift();	# additional deb command options
	my $debfile;

	if ($user_space_only && "$mode" ne "user" && "$mode" ne "any") {
		return;
	}

	$debfile = rpm_resolve("$debpath", $mode);
	if ( "$debfile" eq "" || ! -e "$debfile" ) {
		NormalPrint "Not Found: $debpath $mode\n";
	} else {
		rpm_run_install($debfile, $mode, $options);
	}
}

# TBD - phase out this function (or get all callers to use same options)
sub rpm_install($$)
{
	my $debpath = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	rpm_install_with_options($debpath, $mode, "");
}


# verify the rpmfiles exist for all the RPMs listed
sub rpm_exists_list($$@)
{
	my $debdir = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- any variation found
	my @package_list = @_;	# package names

	foreach my $package ( @package_list )
	{
		if (! rpm_exists("$debdir/$package", $mode) ) {
			return 0;
		}
	}
	return 1;
}

sub rpm_install_list_with_options($$$@)
{
	my $debdir = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	my $options = shift();	# additional rpm command options
	my @package_list = @_;	# package names
	
	foreach my $package ( @package_list )
	{
		rpm_install_with_options("$debdir/$package", $mode, $options);
	}
}

# TBD - phase out this function (or get all callers to use same options)
sub rpm_install_list($$@)
{
	my $debdir = shift();
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	my @package_list = @_;	# package names

	rpm_install_list_with_options($debdir, $mode, "", @package_list);
}

# debpath_list is a list of glob style absolute or relative path to the packages
# including the package name, but excluding package version, architecture and
# .deb suffix
sub rpm_install_path_list_with_options($@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	my $options = shift();	# additional rpm command options
	my @debpath_list = @_;	# deb pathnames

	foreach my $debpath ( @debpath_list )
	{
		rpm_install_with_options("$debpath", $mode, $options);
	}
}

# debpath_list is a list of glob style absolute or relative path to the packages
# including the package name, but excluding package version, architecture and
# .deb suffix
# TBD - phase out this function (or get all callers to use same options)
sub rpm_install_path_list($@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- will install any variation found
	my @debpath_list = @_;	# deb pathnames

	rpm_install_path_list_with_options($mode, "", @debpath_list);
}

# returns 0 on success (or rpms not installed), != 0 on failure
sub rpm_uninstall_list2($$$@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $options = shift();	# additional rpm command options
	my $verbosity = shift();	# verbose or silent
	my @package_list = @_;	# package names
	my $package;
	my $ret = 0;	# assume success

	foreach $package ( reverse(@package_list) )
	{
		$ret |= rpm_uninstall($package, $mode, $options, $verbosity);
	}
	return $ret;
}

# returns 0 on success (or rpms not installed), != 0 on failure
sub rpm_uninstall_list($$@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $verbosity = shift();	# verbose or silent
	my @package_list = @_;	# package names
	my $options = "";
	return rpm_uninstall_list2($mode, $options, $verbosity, @package_list);
}


# uninstall all rpms which match any of the supplied package names
# and based on mode and distro/cpu,
# uninstall is done in a single command
# returns 0 on success (or rpms not installed), != 0 on failure
# Force to uninstall without any concern for dependency.
sub rpm_uninstall_all_list_with_options($$$@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $options = shift();	# additional rpm command options
	my $verbosity = shift();	# verbose or silent
	my @package_list = @_;	# package names
	return rpm_uninstall_list2($mode, $options, $verbosity, @package_list);
}

# uninstall all rpms which match any of the supplied package names
# and based on mode and distro/cpu.
# uninstall is done in a single command so dependency issues handled
# returns 0 on success (or rpms not installed), != 0 on failure
# # TBD - phase out this function (or get all callers to use same options)
sub rpm_uninstall_all_list($$@)
{
	my $mode = shift();	# "user" or kernel rev or "firmware"
						# "any"- checks if any variation of package is installed
	my $verbosity = shift();	# verbose or silent
	my @package_list = @_;	# package names
	return rpm_uninstall_all_list_with_options($mode, "", $verbosity, (@package_list));
}

# see if prereqs for building kernel modules are installed
# return 0 on success, 1 if missing dependencies
sub check_kbuild_dependencies($$)
{
	my $osver = shift();	# kernel rev
	my $srpm = shift();	# what trying to build
	my $dir = "/lib/modules/$osver/build";

	if ( ! $rpm_check_dependencies ) {
		return 0;
	}
	if ( ! -d "$dir/scripts" ) {
		NormalPrint "Unable to build $srpm: $dir/scripts: not found\n";
		NormalPrint "linux-headers-$osver is required to build $srpm\n";
		return 1;	# failure
	}
	return 0;
}

# see if basic prereqs for building RPMs are installed
# return 0 on success, or number of missing dependencies
sub check_rpmbuild_dependencies($)
{
	my $srpm = shift();	# what trying to build
	my $err = 0;
	if (! rpm_is_installed("devscripts", "any")) {
		NormalPrint("devscripts is required to build $srpm\n");
		$err++;
	}
	if (! rpm_is_installed("debhelper", "any")) {
		NormalPrint("debhelper is required to build $srpm\n");
		$err++;
	}
	return $err;
}

sub get_binary_pkg_dir($)
{
	my ($base) = @_;
	return "$base/DEBS";
}

sub get_source_pkg_dir($)
{
	my ($base) = @_;
	return "$base/SDEBS";
}

sub make_build_dirs($$)
{
	my ($BUILD_ROOT, $PKG_DIR) = @_;
	if (0 != system("mkdir -p $PKG_DIR")) {
		NormalPrint "ERROR - mkdir -p $PKG_DIR FAILED\n";
		return 1; # failure
	}
	return 0;
}

sub create_build_command_line($$$$)
{
	my ($SRC_PKG, $BUILD_OUTPUT_DIR, $BUILD_ROOT, $K_VER) = @_;

	my $kernel_version = rpm_tr_os_version($K_VER);
	# get revision from source package revision
	my $rev = $SRC_PKG;
	$rev =~ s/.*-([0-9]+)\.dsc$/$1/;

	my $cmd = "( ";
	$cmd .= "set -e; ";
	$cmd .= "cd $BUILD_OUTPUT_DIR; ";
	$cmd .=	"dpkg-source -x $SRC_PKG; ";
	$cmd .=	"cd *; ";
	$cmd .= "export DEBEMAIL='root <root\@localhost>'; ";
	$cmd .= "dch -b --newversion=$kernel_version-$rev \"Build for current kernel\"; ";
	$cmd .= "export KERNEL_MOD_SIGNING_ENABLED=0; ";
	$cmd .= "export kver=$K_VER; ";
	$cmd .=	"dpkg-buildpackage -uc -us; ";
	$cmd .= ")";

	return $cmd;
}
sub move_packages($$$)
{
	my ($source_dir, $target_dir, $GPU_Install) = @_;
	my $err = 0;
	my $real_target = $target_dir;
	if ( $GPU_Install eq "NV_GPU" ) {
		$real_target = "$target_dir/CUDA";
	} elsif ( $GPU_Install eq "INTEL_GPU" ) {
		$real_target = "$target_dir/ONEAPI-ZE";
	}
	system("mkdir -p $real_target");
	DebugPrint("Moving $source_dir/*.deb to $real_target\n");
	$err = system("mv $source_dir/*.deb $real_target");
	return $err;
}
