#!/usr/bin/perl

$skip=1;

$file=shift;
if($file=~m/noskip/i) {
   $skip=0;
   $file=shift;
}
$noinst=shift;

$exclude_pcommon=" pkgtools bittornado bittorrent ";

$pdir="/root/packages";
$pcom="/root/pcommon";

########## FUNCTIONS ###########
sub ConvertToAltFile
{
  my $altfile=shift;
  $i=rindex($altfile,"/");
  if($i>=0) {
    $altfile=substr($altfile,0,$i+1);
  }
  $altfile.="altversions.txt";
  return($altfile);
}

sub pkgbase {
  my $pkg=shift;
  my $i;
  if(($i=rindex($pkg,"/"))>=0) {
    $pkg=substr($pkg,$i+1);
  }
  $pkg=~s/\.t[gblx]z$//;
  return($pkg);
}

sub package_name {
  my $pkg=shift;
  my $pkgn;
  $_=pkgbase($pkg);
  ($pkgn)=m/(.+)-.+?-.+?-.+?/;
  if(length($pkgn)==0) { $pkgn=$_; }
  return($pkgn);
}

sub package_arch {
  my $pkg=shift;
  my $pkga;
  $_=pkgbase($pkg);
  ($pkga)=m/.+-.+?-(.+?)-.+?/;
  if(length($pkga)==0) { $pkga=$ARCH; }
  return($pkga);
}

sub GetARCH
{
  my $file=shift;
  my $b="";
  if(open(AA,$file)) {
    my $status=0;
    while(<AA>) {
      if($status==0) {
	if(m/^MARCH|if\s*\[\s*-z\s*["']?\$ARCH/) {
	  $status=1;
	}
      }
      if($status==1) {
	$b.=$_;
        if(m/^\s*fi/) {
	  $status=2;
	  last;
	}
      }
    }
    close(AA);
  }
  else {
    $b='if [ -z "$ARCH" ]; then'."\n".
       '  case "$( uname -m )" in'."\n".
       '    i?86) export ARCH=i586 ;;'."\n".
       '       *) export ARCH=$( uname -m ) ;;'."\n".
       '  esac'."\n".
       'fi'."\n";
  }
  return($b);
}

sub CheckPCommon
{
  if($ipkg=~m/-noarch-/ || $fullpkg=~m/-noarch-/)
  {
    $ENV{ARCH}="noarch";
    $extra_arch="ARCH=noarch\n";
    $pcommon=1;
  }
  elsif($ipkg=~m/-fw-/ || $fullpkg=~m/-fw-/)
  {
    $ENV{ARCH}="fw";
    $extra_arch="ARCH=fw\n";
    $pcommon=1;
  }
  if($pcommon && index($exclude_pcommon," $pkgnam ")>=0)
  {
    $pcommon=0;
  }
}

######### MAIN ###########

$ARCH=$ENV{ARCH};
if(length($ARCH)==0) { $ARCH=`uname -m`; chop($ARCH); }

$altfile=ConvertToAltFile($0);

if(!-f $altfile) {
  # Check if it a symlink
  $altfile=ConvertToAltFile(readlink($0));
}
# Load alternated versions:
if(-f $altfile && open(F,"$altfile")) {
  while(<F>)
  {
    chop;
    ($pack,$ver)=m/(\S+?)=(\S+)/;
    $altver{$pack}=$ver;
  }
  close(F);
}


if($file eq "") {
  # Check if exists a SlackBuild file
  $slb=`\\ls *.SlackBuild`;
  (@sbl)=split("\n",$slb);
  if($#slb==0) { 
    # Only 1 file found, use it
    $file=$slb[0];
  }
}

if($file eq "-") {
  # Package name passed as second parameter (e.g. from kde or x11)

  $fullpkg=$noinst;
  $noinst=0;
  $pkgnam=package_name($fullpkg);
  $archtmp=package_arch($fullpkg);
  if(length($archtmp)>0) { $ARCH=$archtmp; }

}
else {
  # Get packaga name-version from build script

  if($noinst eq "NOINST") { $noinst=1; }

  $pkgnam=substr($file,0,index($file,".SlackBuild"));


  if($file=~m/-/ && (! -f $file)) {
    $file=~s/-/_/g;
  }

  if(length($pkgnam)==0) {
    $pkgnam=`pwd`;
    chop($pkgnam);
    $pkgnam=substr($pkgnam,rindex($pkgnam,"/")+1);
    if(length($file)==0) {
      $file="$pkgnam.SlackBuild";
    }
  }

  if($file eq "sendmail.SlackBuild") { $file="SlackBuild-sendmail"; }
}

# Make special package checks:

if($pkgnam eq "aspell-dict" || 
   #$pkgnam eq "slacktrack" ||
   #$pkgnam eq "linuxdoc-tools" ||
   #$pkgnam eq "rust" ||
   #$pkgnam=~m/libX/ ||
   $pkgnam=~m/^kernel/i ||
   0) {
  print "*** $file to be checked manually\n";
  exit(0);
}

if($pkgnam eq "x11" ||
   lc($pkgnam) eq "kde" ||
  0) {
  exit(2);
}

if((!($ARCH=~/86/) &&
    ($pkgnam eq "vbetool" || 
     $pkgnam eq "isapnptools" || 
     $pkgnam eq "lilo" || 
     $pkgnam eq "elilo" || 
     $pkgnam eq "libx86" || 
     $pkgnam eq "svgalib" || 
     $pkgnam eq "seejpeg" || 
     $pkgnam eq "libva-intel-driver" || 
     $pkgnam eq "intel-vaapi-driver" || 
     #$pkgnam eq "gnu-efi" || 
     $pkgnam eq "syslinux")) || 
   ($altver{$pkgnam} eq "0.0.0/0" && !defined($altver{"${ARCH}:$pkgnam"})) ||
   0) {
  if($skip) {
    print "*** $file skipped on ${ARCH} platform\n";
    exit(0);
  }
}

if($altver{"${ARCH}:$pkgnam"} eq "0.0.0/0")
{
  if($skip) {
    print "*** $file disabled on ${ARCH} platform\n";
    exit(0);
 }
}
if($altver{"${ARCH}:$pkgnam"} eq "-1/-1")
{
  # Only to create ad exception on the default, such as for intel-microcode
  delete($altver{"${ARCH}:$pkgnam"});
  delete($altver{"$pkgnam"});
}

$pkgnam=~s/qt-nowebkit/qt/;

if($ENV{ARCH} eq "" && 0) 
{
   print "ARCH env should be set!\n";
   exit(3);
}

$packagedir="/var/log/packages";
$ipkg=`(cd $packagedir/;\\ls ${pkgnam}-* )2>/dev/null | xargs`;
chop($ipkg);
if(length($ipkg)==0)
{
  $packagedir=$pdir;
  $ipkg=`(cd $packagedir/;\\ls -t */${pkgnam}-*.t?z ) 2>/dev/null | grep -vE '^old_|^temp' | xargs`;
  chop($ipkg);
  if(!$noinst) {
    $noinst=-1;
  }
}
@ipkg=split(" ",$ipkg);
$ipkg="";
foreach $pp (@ipkg) {
  $pkgn=package_name($pp);
  if($pkgn eq $pkgnam) {
    $ipkg=pkgbase($pp);
    $packagefile="$packagedir/$pp";
    last;
  }
}


CheckPCommon();

if($file ne "-") 
{
  if(!open(F,"$file"))
  {
     print "Cannot check package $file: $!\n";
     exit(2);
  }

  if(length($ENV{ARCH})>0) { $arch=3; }
  while(<F>)
  {
    #if(m/cd.*dirname \$0/) { next; }
    if(m/cd.*dirname \$0/) { s/cd.*?dirname \$0.*?\)//;s/.*?;//; }
    if(m/^BUILD/) { $build=1; }
    if(m/^\s*VERSION/) { 
      if($pkgnam ne "boost") {
	$version=1; 
	if($tarbver) { $_=""; } 
      }
    }
    if(m/^\s*PKG_VERSION/) { $version=1; s/PKG_VERSION/VERSION/; }
    if(m/^ZONE_VERSIONS/) { $version=1; s/ZONE_VERSIONS/VERSION/;}
    if(m/^VERSION_NEW/) { $version=1; s/VERSION_NEW/VERSION/;}
    if(m/^ALPINEBUILD/) { $build=1; s/ALPINE//;}
    if(m/^PKGVER/) { $version=1; s/PKGVER/VERSION/;}
    if(m/^VERGNUCHESS/) { $version=1; s/VERGNUCHESS/VERSION/;}
    if(m/^TARBVER/) { $tarbver=1; s/TARBVER/VERSION/;}
    if(m/^OLD_STYLE/) { $oldstyle=1; }
    if(m/^SUB=/) { $sub=1; }
    if(m/PRINT_PACKAGE_NAME/) { $printpackagename=1; }
    $buffer.=$_;
    if(m/^\s*QTVERSION/) { $version=1; $buffer.="VERSION=\${QTVERSION}\n"; }
    if(m/^\s*QTBUILD/) { $build=1; $buffer.="BUILD=\${QTBUILD}\n"; }
    if(m/^DEBPATCH/) { 
	$buffer.="VERSION=\${VERSION}_\$DEBPATCH\n";
    }
    if(m/^EXTRAVERSION/) { 
	$buffer.="VERSION=\${VERSION}_\$EXTRAVERSION\n";
    }
    if(m/^BRANCH=/) { 
	$buffer.="VERSION=\${BRANCH}_\${VERSION}\n";
    }
    if(!$arch && m/^\s*if.*-z "\$.*ARCH/) {
      $arch=1;
    }
    if($arch==1 && m/^\s*fi/) {
      $arch=2;
    }
    chop;
    s/\s+//g;
    if($version && $build && $arch>=2 && length($_)==0) { last; }
  }
  if($pkgnam=~m/bash|readline/)
  {
    # Checking for PATCHLEVEL
    $if=0;
    while(<F>)
    {
      if(m/PRINT_PACKAGE_NAME/) { $printpackagename=1; }
      if(m/PATCHLEVEL/) {
	$buffer.=$_;
	if(m/^if/) {
	  $if=1;
	}
      }
      if(m/^fi/ && $if)
      {
	$buffer.=$_;
	$buffer.="VERSION=\$VERSION.\$PATCHLEVEL\n";
	last;
      }
    }
  }
  # Check for  PRINT_PACKAGE_NAME
  while(<F>)
  {
    if(m/PRINT_PACKAGE_NAME/) {
      $printpackagename=1;
    }
  }
  close(F);

  if($printpackagename) {
    $ENV{PRINT_PACKAGE_NAME}=1;
    $fullpkg=`sh $file`;
    chomp($fullpkg);
    $fullpkg=~s/\....$//;
    CheckPCommon();
  }
  else {
    $ENV{PRINT_PACKAGE_NAME}=undef;
    # Check for x11 or kde build script
    $b2="#!/bin/bash\n";
    $b2.="PKGNAM=\"$pkgnam\"\n";
    if( -f "x11-build-script.sh" || -f "x11.SlackBuild" )
    {
       $buffer=$b2;
       $buffer.="BUILD=".`cat build/$pkgnam`."\n";
       $buffer.="VERSION=".`echo src/*/${pkgnam}-*.tar* | rev | cut -f 3- -d . | cut -f 1 -d - | rev`."\n";
       if( -f "x11-build-script.sh") {
         $buffer.=GetARCH("x11-build-script.sh");
       }
       else {
         $buffer.=GetARCH("x11.SlackBuild");
       }
    }
    elsif( -f "KDE.SlackBuild" || -f "kde.SlackBuild" ) 
    {
       $buffer=$b2;
       $buffer.="BUILD=".`cat build/$pkgnam`."\n";
       $ver=`find src -name "${pkgnam}-*.tar*z" | rev | cut -f 3- -d . | cut -f 1 -d - | rev`;
       chomp($ver);
       if(length($ver)==0) { # No more useful
	 $ver=`echo src/*/${pkgnam}-*.tar*z | rev | cut -f 3- -d . | cut -f 1 -d - | rev`;
	 chomp($ver);
       }
       $buffer.="VERSION=$ver\n";
       $buffer.=GetARCH("KDE.options");
    }
  }
}

# OK, now checking the version. Use the file anyway even when
# not needed ($fullpkg already got)

if($sub) {
  $buffer.="VERSION=\${VERSION}_\$SUB\n";
}

#print "Checking $file...\n";


if($oldstyle) {
  $buffer.="VERSION=\$OLD_STYLE\n";
}
$buffer.='VERSION=$(echo $VERSION|sed "s/-/_/g")'."\n";
$buffer.="PKGNAM=$pkgnam\n";
$buffer.="pkg='$ipkg'\n";
$buffer.="$extra_arch\n";

$buffer.='
echo "$PKGNAM-$VERSION-$ARCH-$BUILD"
';

$TMP=$ENV{TMP};
if(length($TMP)==0) { $TMP="/tmp"; }

if(open(W,">$TMP/pkgcheck$$.sh"))
{
  print W $buffer;
  close(W);
  #$oldarch=$ENV{ARCH};
  #if(length($ENV{ARCH})==0) {
  #  $ENV{ARCH}=$ARCH;
  #}
  $out=`sh $TMP/pkgcheck$$.sh 2>/dev/null`;
  #$ENV{ARCH}=$oldarch;
  system("cp $TMP/pkgcheck$$.sh $TMP/pkgcheck.sh");
  unlink("$TMP/pkgcheck$$.sh");
  if(length($out)>0) {
    if(length($fullpkg)==0) {
      $fullpkg=$out;
      chomp($fullpkg);
    }
    if(length($fullpkg)>0)
    {
      @ipkg=split("\n",$fullpkg);
      foreach $pp (@ipkg) {
	$pkgn=package_name($pp);
	if($pkgn eq $pkgnam) {
	  $fullpkg=pkgbase($pp);
	  last;
	}
      }
      if($ipkg ne $fullpkg) {
	if(length($ENV{ARCH})==0) {
	  $archtmp=package_arch($fullpkg);
	  if(length($archtmp)>0) { $ARCH=$archtmp; }
	}
        # Check if exists and alternate version
	if(!defined($altver=$altver{"${ARCH}:$pkgnam"}))
	{
	  $altver=$altver{$pkgnam};
	}
	if(length($altver)>0) {
	  ($ver,$build)=split('/',$altver);
	  $fullpkg="$pkgnam-$ver-${ARCH}-$build";
	}
      }
      if($ipkg ne $fullpkg && ($pcommon || $noinst || $pkgnam=~m/php|bind/)) # LB-20230729: Added $pcommon; do not extend to all packages since it could be disk-intesive operation
      {
	# Check if it present in packages (like php 5.6...)
	$packagedir=$pdir;
	$ppkg=`(cd $packagedir;\\ls */${pkgnam}-*.t?z ) 2>/dev/null | grep -vE '^old_|^temp' | xargs`;
	chop($ppkg);
	@ipkg=split(" ",$ppkg);
	foreach $pp (@ipkg) {
	  $pkgn=pkgbase($pp);
	  if($pkgn eq $fullpkg) {
	    $ipkg=$fullpkg;
	    $packagefile="$packagedir/$pp";
	    if($noinst==0) { $noinst=-2; }
	    last;
	  }
	}
      }
      if($ipkg ne $fullpkg && $pcommon) {
	# Check if it present in common packages
	$packagedir=$pcom;
	$ppkg=`(cd $packagedir/;\\ls */${pkgnam}-*.t?z ) 2>/dev/null | grep -vE '^old_|^temp' | xargs`;
	chop($ppkg);
	@ipkg=split(" ",$ppkg);
	foreach $pp (@ipkg) {
	  $pkgn=pkgbase($pp);
	  if($pkgn eq $fullpkg) {
	    $packagefile="$packagedir/$pp";
	    print STDERR "$packagefile\n";
	    print "Common version for package $pkgnam:\n";
	    print "- Found:    $fullpkg\n";
	    exit(99);
	  }
	}
      }
      if($ipkg ne $fullpkg) {
	print STDERR "$pkgnam\n";
	print "Version for package $pkgnam mismatch:\n";
	print "- Expected: $fullpkg\n";
	print "- Found:    $ipkg\n";
	if($pcommon) { exit 10; }
	exit 1;
      }
      elsif($noinst<0) {
	print STDERR "$packagefile\n";
	print "Version found but not installed for package $pkgnam:\n";
	print "- Found:    $fullpkg\n";
	exit(100);
      }
      exit 0;
    }
    print STDERR "$pkgnam\n";
    print $out;
    exit 1;
  }
  exit 0;
}
else {
  print "Cannot create shell: $!\n";
  exit 2;
}
