#!/usr/bin/perl

# rpmdep-pipe
# This script queries the rpm database to extract what dependencies a
# package has and classify them.

# note to self:
#   this works for simple queries.  To make it recursive, I'll have to make
#   sure I don't lose my key to the rpm database which is the simple name.
#   The full rpm package name with version number looks cool, but is not
#   useful for making further queries into the database.  I'll probably
#   have to maintain both names in some fashion.

($name,$start_flag) = @ARGV;

my @out=();

if ($name =~ /\.rpm/) {
  if (-e ".pathway") {
    $name = ".pathway/".$name;
  }
  @out = `rpm -qpR $name`;
}
else {
  $pack = `rpm -q $name 2>&1`;
  chomp($pack);
  # print "..$pack..\n";
  if ($pack =~ /not install/ ) {
    @out = search_pack($name);
  }
  else {
    @out = `rpm -q --queryformat "[%{requirename} %{requireflags:depflags} %{requireversion}\n]" $pack`;
    # @out = `rpm -q -R $pack`;
  }
}

$cnt = @out;

if ($cnt==0) {
  #  print STDERR "did not find anything\n";
  exit 0;
}
else {
  #  print STDERR @out;
  #  print STDERR $cnt;
  
  if ($start_flag==1 && $cnt==1 && $out[0]=="") {
    print "package $name has no dependency.\n";
    exit (0);
  }
  chomp(@out);
  
  my%deplist;
  
  foreach $line (@out) {
    #	print "$line\n";
    chomp $line;
    if ($line =~ "/") {
      #		print "File: $line ";
      $owning_package = get_file($line);
      #		print "--> $owning_package\n";
      $deplist{$owning_package} = 1;
    } elsif ($line =~ /\.so/) {
      #		print "Library: $line";
      $owning_package = get_lib($line);
      #		print "--> $owning_package\n";
      if ($owning_package!=1){
	$deplist{$owning_package} = 1;
      }
    } elsif ($line =~ /(none)/) {
      ;
    } else {
      #		print "Package or virtual package: $line ";
      $owning_package = get_virt($line);
      #		print "--> $owning_package\n";
      $deplist{$owning_package} = 1;
    }
  }

  #@sorteddeps = sort(keys(%deplist));
  foreach (sort(keys(%deplist))) {
    print "$_\n";
  }
}

sub get_lib {
  # the parameter is a shared library
  # eg. ld-linux.so.2
  my($rpmlibname) = @_;
  $rpmlibname =~ s/\s+//; # remove all space
  $rpmlibname =~ s/\>.*//; # ignore version
  #print "=$rpmlibname=\n";
  my $fullname;
  my(@libpath) = `cat /etc/ld.so.conf`;
  push @libpath, "/lib";
  
  # first find true path to needed file
  foreach $path (@libpath) {
    chomp $path;
    #print "Looking at $path/$rpmlibname...\n";
    if (-l "$path/$rpmlibname") {
      #print "It's a symlink!\n";
      $_ = readlink("$path/$rpmlibname");
      $fullname = "$path/$_";
      #print "It points to $fullname\n";
      last;
    } elsif (-x "$path/$rpmlibname") {
      #print "It's executable!\n";
      $fullname = "$path/$rpmlibname";
    }
  }
  
  # now find owner of that file
  if ($fullname) { 
#    $owner = `rpm -qf --queryformat "%{name}\n" $fullname`;
    $owner = `rpm -qf $fullname`;
    chomp($owner);
    return $owner;
  } else {
    return 1;
  }
}

sub get_file {
  my($filename) = @_;
#  my $owner = `rpm -qf --queryformat "%{name}\n" $filename`;
  my $owner = `rpm -qf $filename`;
  chomp($owner);
  return $owner;
}

sub get_virt {
  # possible subcases: virtual package ( snack )
  # package version requirement ( pythonlib >= 1.21 )
  # actual package ( python ) 
  
  my($virtpackage) = @_;
  chomp $virtpackage;
  #print "looking for $virtpackage...\n";
  
  # try looking for virtual package
  my $package;
  ($package) = split(" ",$virtpackage); # keep only first word
  my $results = `rpm -q --whatprovides $package 2>&1`;
  chomp($results);
  #print "results $results";
  if ((index($results, "no package provides") == -1) or 
      ($results eq "")) {
    return $results;
  }
  
  #print "package $package\n";
  
  #	my $search = `find /usr -name $package*.{$HOSTTYPE}.rpm`;
  
#  my $owner = `rpm -q --queryformat "%{name}\n" $package`;
  my $owner = `rpm -q $package`;
  chomp($owner);
  return $owner;
}

sub search_pack{
  my($packname) = @_;
  my $cnt=0;
  my $postfix = '.$HOSTTYPE.rpm';
  
  #  print "Search package name $packname\n";
  
  if (-e "./.pathway") {
    @packfile = `find ./.pathway/ -name $packname-*$postfix`;
  }
  else {
    @packfile = `find -name $packname-*$postfix`;
  }
  
  $cnt = @packfile;

  if ($cnt!=0) {
    @result = `rpm -qpR $packfile[0]`;

    return @result;
  }
  else {
    return;
  }
}
