File Coverage

blib/lib/File/VirusScan/Engine/Command/FPROT/Fpscan.pm
Criterion Covered Total %
statement 22 52 42.3
branch 0 22 0.0
condition 0 5 0.0
subroutine 8 9 88.8
pod 1 2 50.0
total 31 90 34.4


line stmt bran cond sub pod time code
1             package File::VirusScan::Engine::Command::FPROT::Fpscan;
2 1     1   93535 use strict;
  1         8  
  1         23  
3 1     1   5 use warnings;
  1         2  
  1         19  
4 1     1   4 use Carp;
  1         2  
  1         54  
5              
6 1     1   323 use File::VirusScan::Engine::Command;
  1         2  
  1         5  
7 1     1   42 use vars qw( @ISA );
  1         2  
  1         38  
8             @ISA = qw( File::VirusScan::Engine::Command );
9              
10 1     1   5 use Cwd 'abs_path';
  1         2  
  1         34  
11              
12 1     1   340 use File::VirusScan::Result;
  1         2  
  1         313  
13              
14             sub default_arguments
15             {
16 5     5 0 35 return [ qw( --report --archive=5 --scanlevel=4 --heurlevel=3 ) ];
17             }
18              
19             sub scan
20             {
21 0     0 1   my ($self, $path) = @_;
22              
23 0           my $abs = abs_path($path);
24 0 0 0       if ($abs && $abs ne $path) {
25 0           $path = $abs;
26             }
27              
28 0           my ($exitcode, $scan_response) = eval { $self->_run_commandline_scanner(join(' ', $self->{command}, @{ $self->{args} }, $path, '2>&1')); };
  0            
  0            
29              
30 0 0         if($@) {
31 0           return File::VirusScan::Result->error($@);
32             }
33              
34 0 0         if(0 == $exitcode) {
35 0           return File::VirusScan::Result->clean();
36             }
37              
38             # bit 1 (1) ==> At least one virus-infected object was found (and
39             # remains).
40 0 0         if( $exitcode & 0b1 ){
41 0           my ($virus_name) = $scan_response =~ m/^\[Found\s+[^\]]*\]\s+<([^ \t\(>]*)/m;
42 0   0       $virus_name ||= 'unknown-FPSCAN-virus';
43 0           return File::VirusScan::Result->virus($virus_name);
44             }
45              
46             # bit 2 (2) ==> At least one suspicious (heuristic match) object
47             # was found (and remains).
48 0 0         if ($exitcode & 0b10) {
49 0           return File::VirusScan::Result->virus('FPSCAN-suspicious');
50             }
51              
52             # bit 3 (4) ==> Interrupted by user (SIGINT, SIGBREAK).
53 0 0         if ($exitcode & 0b100) {
54 0           return File::VirusScan::Result->error('Interrupted by user');
55             }
56              
57             # bit 4 (8) ==> Scan restriction caused scan to skip files
58             # (maxdepth directories, maxdepth archives,
59             # exclusion list, etc).
60              
61 0 0         if ($exitcode & 0b1000) {
62 0           return File::VirusScan::Result->error('Scanning restrictions triggered abort due to skipped files');
63             }
64              
65             # bit 5 (16) ==> Platform error (out of memory, real I/O errors,
66             # insufficient file permission etc.)
67              
68 0 0         if ($exitcode & 0b10000) {
69 0           return File::VirusScan::Result->error('Platform error (out of memory, I/O errors, etc)');
70             }
71              
72             # bit 6 (32) ==> Internal engine error (whatever the engine fails
73             # at)
74 0 0         if ($exitcode & 0b100000) {
75 0           return File::VirusScan::Result->error('Internal virus engine error');
76             }
77              
78             # bit 7 (64) ==> At least one object was not scanned (encrypted
79             # file, unsupported/unknown compression method,
80             # corrupted or invalid file).
81 0 0         if ($exitcode & 0b1000000) {
82 0           return File::VirusScan::Result->error('At least one object not scannable');
83             }
84              
85             # bit 8 (128) ==> At least one object was disinfected (clean now).
86             # Should not happen as we aren't requesting disinfection ( at least
87             # in this version).
88 0 0         if ($exitcode & 0b10000000) {
89 0           return File::VirusScan::Result->virus('Scanner claims to have cleaned a virus, but cannot in this mode');
90             }
91              
92 0           return File::VirusScan::Result->error("Unknown return code: $exitcode");
93             }
94              
95             1;
96             __END__