File Coverage

blib/lib/File/VirusScan/Engine/Daemon/Sophos/Sophie.pm
Criterion Covered Total %
statement 33 64 51.5
branch 3 20 15.0
condition 0 7 0.0
subroutine 10 11 90.9
pod 2 2 100.0
total 48 104 46.1


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