File Coverage

blib/lib/File/VirusScan/Engine/Command/FPROT/Fpscan.pm
Criterion Covered Total %
statement 25 51 49.0
branch 1 22 4.5
condition 0 2 0.0
subroutine 9 9 100.0
pod 1 2 50.0
total 36 86 41.8


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