#!/usr/bin/perl -w
########################################
## Print dtype.org MSD ranking for your signators
## by Ralf Hüls <R.Huels@ping.de>
##
## M. Drew Streib analyzes the key ring of the keys.us.pgp.net keyserver
## on a monthly basis. He uses the "mean shortest distance" (MSD) from
## all keys in the largest strongly connected set of public keys as a
## relative measure of trust.
## Read more about these analyses on http://www.dtype.org/keyanalyze/
##
## This program lists the signators of a given public key, ranked
## by MSD.
##
## Usage: rank.pl
## The program will ask for the key ID interactively.
##
## Output:
## lists.txt  List of Key ID, rank, MSD and main UID
##
## Needs:
## - GnuPG 1.0.7 (http://www.gnupg.org/)
## - Perl 5      (http://www.perl.com/)
## - msd-sorted.txt from http://www.dtype.org/keyanalyze
##
## (c) 25-06-2002 by Ralf Hüls <R.Huels@ping.de>
##
## This program is a dirty hack, use it at your own risk ;-)
## Non-commercial use and distribution of this program is permitted.
## If you modify this program to create something useful or
## interesting, I'd like to hear about it.
##
## Ralf Hüls <R.Huels@ping.de> 
## http://www.teleute.ping.de/
## DSA key: E131C5A4
## RSA key: 4931A04F
####################################################################
use strict;

my $line;
my $sig;
my $key;
my @line;
my @output;
my %signators;
my %rank;
my %data;
my %mean;

print "Key-ID:";
$key=<STDIN>;
chomp $key;
die "Bad key ID!" unless ((uc $key) =~ /^[0123456789ABCDEF]{8}$/) ;

open(F,'msd-sorted.txt');
while (defined ($line=<F>)) {
  chomp $line;
  @line=split / +/,$line;
  $rank{$line[3]}=$line[1];  
  $mean{$line[3]}=$line[4];  
}
close F;

open(S,"gpg --list-sigs $key|") or die "$!"; 
@output=<S>;
  close S;


foreach (@output)
  {
    if (/^sig/)
      {      
	$sig=substr($_,12,8);
	$signators{$sig}=1;
	$data{$sig}=substr($_,32,57);
	chomp $data{$sig};
      }
  }
    
open(F,'>ranks.txt');
foreach (sort by_rank keys %signators)
  {
    print "$_ ";
    print F "$_ ";
    if (defined $rank{$_}) {
      printf "%5d %6.4f ",$rank{$_},$mean{$_};
      printf F "%5d %6.4f ",$rank{$_},$mean{$_};
    }
    else {
      print "             ";
      print F "             ";
    }
    print "$data{$_}\n";
    print F "$data{$_}\n";
  }
close F;


#################################
sub by_rank {
  unless (defined $rank{$a}) {
    return 1;
  }
  unless (defined $rank{$b}) {
    return -1;
  }
  ($rank{$a} <=> $rank{$b});
}
