#!/usr/bin/perl
my $full_can_html=shift;
my $dsa_list=shift;
my $dtsa_list=shift;
my $our_list=shift;
my %cans;
sub read_dsa {
my $list=shift;
open (DSA, "<$list") || die "$list: $!\n";
my $dsa;
while () {
if (/^\[/) {
($dsa)=m/(DT?SA-.*?) /;
}
if (/\{(CAN|CVE)/) {
my ($canlist)=m/\{(.*)\}/;
foreach my $can (split ' ', $canlist) {
$can=~s/CVE-/CAN-/g;
next unless $can=~/^CAN-\d+/;
$cans{$can}{can}=$can;
push @{$cans{$can}{dsa}}, $dsa;
$can=~s/CAN-/CVE-/g;
$cans{$can}{can}=$can;
push @{$cans{$can}{dsa}}, $dsa;
}
}
}
close DSA;
}
read_dsa($dsa_list);
read_dsa($dtsa_list);
my %listedcans;
open (FULL_CAN, "<$full_can_html") || die "$full_can_html: $!\n";
my $can;
while () {
if (m!(CAN-\d+-\d+)!) {
$can=$1;
$cans{$can}{can}=$can;
$listedcans{$can}=1;
}
elsif (m!(CVE-\d+-\d+)!) {
$can=$1;
$cans{$can}{can}=$can;
$listedcans{$can}=1;
}
if (m!\*\*\s+RESERVED\s+\*\*!) {
$cans{$can}{reserved}=1;
}
if (m!\*\*\s+REJECT\s+\*\*!) {
$cans{$can}{rejected}=1;
}
if (m!Description:\s*
\s*(.*)! &&
! m!\*\*\s+RESERVED\s+\*\*! && ! m!\*\*\s+REJECT\s+\*\*!) {
$cans{$can}{description}="($1 ...)";
}
}
close FULL_CAN;
my $stopped=0;
my @out;
sub docan {
my $can=shift;
push @out, "$can".(length $cans{$can}{description} ? " ".$cans{$can}{description} : "")."\n";
if ($cans{$can}{reserved}) {
push @out, "\tNOTE: reserved\n";
}
if ($cans{$can}{rejected}) {
push @out, "\tNOTE: rejected\n";
}
if ($cans{$can}{dsa}) {
push @out, "\t{".join(" ", @{$cans{$can}{dsa}})."}\n";
}
if ($cans{$can}{notes}) {
foreach (@{$cans{$can}{notes}}) {
push @out, "\t$_\n";
}
}
if (! $cans{$can}{reserved} && ! $cans{$can}{rejected} &&
! $cans{$can}{dsa} && ! $cans{$can}{notes} &&
! $stopped) {
push @out, "\tTODO: check\n";
}
delete $cans{$can};
}
open (IN, "<$our_list") || die "$our_list: $!\n";
my $can;
while () {
chomp;
if (/^((?:CAN|CVE)-(?:[0-9]+|[A-Z]+)-(?:[0-9]+|[A-Z]+))\s*(.*)/) {
my $desc=$2;
docan($can) if $can;
$can=$1;
if (length $desc && $desc !~ /^\(.*\)$/ &&
(! exists $cans{$can}{description} ||
! length $cans{$can}{description})) {
$cans{$can}{description}=$desc;
}
}
elsif (/^\s+NOTE:\s*(reserved|rejected)\s*$/) {
# skip it
}
elsif (/^\s+NOTE: covered by DT?SA.*/) {
# skip it (old form)
}
elsif (/^\s+{DT?SA.*/) {
# skip
}
elsif (/^\s+(.*)/ && $can) {
push @{$cans{$can}{notes}}, $1;
}
elsif (/^STOP/) {
docan($can) if $can;
push @out, "$_\n";
$stopped=1;
$can='';
}
else {
docan($can) if $can;
push @out, "$_\n" if length $_;
$can='';
}
}
close IN;
docan($can) if $can;
foreach my $can (reverse sort { $cans{$a}{can} cmp $cans{$b}{can} } keys %cans) {
next unless $listedcans{$can};
print $can.(length $cans{$can}{description} ? " ".$cans{$can}{description} : "")."\n";
if ($cans{$can}{reserved}) {
print "\tNOTE: reserved\n";
}
if ($cans{$can}{rejected}) {
print "\tNOTE: rejected\n";
}
if ($cans{$can}{dsa}) {
print "\t{".join(" ", @{$cans{$can}{dsa}})."}\n";
}
if (!$cans{$can}{reserved} || $cans{$can}{rejected} || $cans{$can}{dsa}) {
print "\tTODO: check\n";
}
}
print @out;