File Coverage

blib/lib/File/VirusScan/Engine/Daemon/Sophos/Sophie.pm
Criterion Covered Total %
statement 36 63 57.1
branch 4 20 20.0
condition 0 4 0.0
subroutine 11 11 100.0
pod 2 2 100.0
total 53 100 53.0


line stmt bran cond sub pod time code
1             package File::VirusScan::Engine::Daemon::Sophos::Sophie;
2 1     1   49935 use strict;
  1         2  
  1         24  
3 1     1   3 use warnings;
  1         1  
  1         17  
4 1     1   3 use Carp;
  1         1  
  1         42  
5              
6 1     1   261 use File::VirusScan::Engine::Daemon;
  1         3  
  1         6  
7 1     1   42 use vars qw( @ISA );
  1         1  
  1         34  
8             @ISA = qw( File::VirusScan::Engine::Daemon );
9              
10 1     1   361 use IO::Socket::UNIX;
  1         8276  
  1         4  
11 1     1   374 use Cwd 'abs_path';
  1         1  
  1         31  
12              
13 1     1   322 use File::VirusScan::Result;
  1         2  
  1         327  
14              
15             sub new
16             {
17 9     9 1 11311 my ($class, $conf) = @_;
18              
19 9 100       24 if(!$conf->{socket_name}) {
20 1         11 croak "Must supply a 'socket_name' config value for $class";
21             }
22              
23 8         17 my $self = { socket_name => $conf->{socket_name}, };
24              
25 8         34 return bless $self, $class;
26             }
27              
28             sub _get_socket
29             {
30 1     1   891 my ($self) = @_;
31              
32 1         9 my $sock = IO::Socket::UNIX->new(Peer => $self->{socket_name});
33 1 50       252 if(!defined $sock) {
34 1         18 croak "Error: Could not connect to sophie daemon at $self->{socket_name}";
35             }
36              
37 0         0 return $sock;
38             }
39              
40             sub scan
41             {
42 1     1 1 1010 my ($self, $path) = @_;
43              
44 1 50       47 if(abs_path($path) ne $path) {
45 1         16 return File::VirusScan::Result->error("Path $path is not absolute");
46             }
47              
48 0           my $sock = eval { $self->_get_socket };
  0            
49 0 0         if($@) {
50 0           return File::VirusScan::Result->error($@);
51             }
52              
53 0 0         if(!$sock->print("$path\n")) {
54 0           $sock->close;
55 0           return File::VirusScan::Result->error("Could not get sophie to scan $path");
56             }
57              
58 0 0         if(!$sock->flush) {
59 0           $sock->close;
60 0           return File::VirusScan::Result->error("Could not get sophie to scan $path");
61             }
62              
63 0           my $scan_response;
64 0           my $rc = $sock->sysread($scan_response, 256);
65 0           $sock->close();
66              
67 0 0         if(!$rc) {
68 0           return File::VirusScan::Result->error("Did not get response from sophie while scanning $path");
69             }
70              
71 0 0         if($scan_response =~ m/^0/) {
72 0           return File::VirusScan::Result->clean();
73             }
74              
75 0 0         if($scan_response =~ m/^1/) {
76 0           my ($virus_name) = $scan_response =~ /^1:(.*)$/;
77 0   0       $virus_name ||= 'Unknown-sophie-virus';
78 0           return File::VirusScan::Result->virus($virus_name);
79             }
80              
81 0 0         if($scan_response =~ m/^-1:(.*)$/) {
82 0           my $error_message = $1;
83 0   0       $error_message ||= 'unknown error';
84 0           return File::VirusScan::Result->error($error_message);
85             }
86              
87 0           return File::VirusScan::Result->error('Unknown response from sophie');
88             }
89              
90             1;
91             __END__