#!/usr/bin/perl -w
#$Header: sunfingerprint,v0.9 2000/12 afb$
#$! sunfingerprint: checks file list against Suns md5 database
# reads input file/stdin, of the format:
# /usr/bin/ls
# /usr/bin/cat
# that is, one file per line, md5's the files and fetches the results
+of
# a search against Sun's md5 executable db.
# Relies on some formatting of Sun's results page, which may vary some
+day.
# Always tests the md5 executable, also.
# fixed 20/0 matches oops - multiple matches appear for same exe in mu
+ltiple
# Sol versions
# added -l libs flag so you can check lib files (not executables)
require LWP::UserAgent;
use Getopt::Std;
use strict;
my $debug = 0;
my $md5 = "/usr2/local/bin/md5";
my $request;
my $output_all = 0;
my $errors_only = 0;
my $un_html = 1;
# Sun's fingerprint site
my $request_http = "http://sunsolve.Sun.COM/pub-cgi/fileFingerprints.p
+l";
my $Usage = "Usage: $0 [-d X|-l|-e|-h|-o X] file_list
file_list: a text file w/ full path names for the files to be viewe
+d
use - to use stdin, e.g.: find /bin -print | $0
-d X debug level X
-h leave html tags in output
-e errors only
-l libs, ignore executable status
-o X output level X (0 matches only, 1 Sun results,
2 full text, 3 full html page)
";
my %opts;
# must have a file list
die "$Usage" unless @ARGV;
getopts('lho:d:e',\%opts) or die "$Usage";
$debug = $opts{d} ? $opts{d} : 0;
$errors_only = 1 if $opts{e};
$un_html = 0 if $opts{h};
$output_all = $opts{o} ? $opts{o} : 0;
$output_all = 0 if $errors_only;
my $mdlist;
my %mdlist;
my %matches;
my $mdhash;
# read input, check file's existence/executable
while (<>) {
chomp;
next unless /^\s+\//;
$mdlist{$_} = "Not Found!";
if ( -s $_ ) {
$mdlist .= "$_ " ;
$mdlist{$_} = "Found";
if ( ! -x $_ ) {
$mdlist{$_} .= ", Not Executable" unless $opts{l};
} # if ! -x
} # if -s
} # while <>
# add md5 exe to list
$mdlist .= "$md5";
# ugly hack
$mdlist{$md5} = "Found";
# md5 the files
open(MD5, "$md5 $mdlist | ") or die "can't open md5 $md5: $!";
while (<MD5>) {
$mdhash .= "$_";
}
close MD5;
# fetch the cgi results from sun
my $ua = LWP::UserAgent->new;
print STDERR "POSTing $mdhash to $request_http\n" if $debug > 20;
if ( $mdhash ) {
#$request = new HTTP::Request POST => $request_http;
$request = HTTP::Request->new('POST', $request_http);
$request->content_type('application/x-www-form-urlencoded');
$request->content("md5list=$mdhash");
} else {
die "$Usage";
}
print STDERR "Request: ", $request->content, "\n" if $debug > 20;
my $response = $ua->request($request); # actually fetch the doc
if ( $response->is_success ) {
# split up the html return and process the lines between the
# "Results ..." line and the end of the list </dl>
my $pr = 0;
my $file_path;
print STDERR "Success\n" if $debug > 10;
foreach ( split(/\n/, $response->content) ) {
next if /^\s*$/;
if ( $pr ) {
last if /<\/DL>/;
s/<[ =#\/\w]+>//g if $un_html;
# line w/ sun's response:
# 36e7b0c2c6b2b391722c2471688a060b - (/usr/bin/ls) - 1 match(es)
if ( /match/ ) {
print STDERR "match: $_\n" if $debug > 2;
# get file name and matches
/\((\S+)\) - (.*)/;
$file_path = $1;
# add Sun's response
$mdlist{$file_path} .= ", $2 w/ Sun";
$matches{$file_path} = "$_\n" if $output_all;
} else {
$matches{$file_path} .= "$_\n" if $output_all > 1 and $file_p
+ath;
}
} # if pr
# start printing
$pr++ if /Results of Last Search/i;
} # foreach content
# output the final data, input files and any results
if ( $output_all != 3 ) {
foreach my $file ( sort keys %mdlist ) {
if ( $errors_only ) {
$_ = $mdlist{$file};
print "$file: $mdlist{$file}\n" if /Not/ or / 0 match/;
} else {
if ( $matches{$file} ) {
print "$file: $matches{$file}\n";
} else {
print "$file: $mdlist{$file}\n\n";
} # if matches
} # if errors_only
} # foreach file
} else {
# dump the whole page, if wanted
print "Content: ", $response->content, "\n";
} # if output_all == 3
} else {
print STDERR "Result: cgi request failed! $request_http\n";
}
|