littleneck_clamav 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +2 -0
- data/LICENSE +19 -0
- data/README.md +50 -0
- data/lib/littleneck_clamav/clam.rb +81 -0
- data/lib/littleneck_clamav/clamd.rb +13 -0
- data/lib/littleneck_clamav/error.rb +5 -0
- data/lib/littleneck_clamav/result.rb +29 -0
- data/lib/littleneck_clamav.rb +45 -0
- data/spec/clam_spec.rb +19 -0
- data/spec/clamd_spec.rb +17 -0
- data/spec/littleneck_clamav_spec.rb +97 -0
- data/spec/result_spec.rb +55 -0
- data/spec/spec_helper.rb +11 -0
- data/spec/support/factories.rb +9 -0
- data/spec/support/shared_examples.rb +131 -0
- metadata +120 -0
data/.rspec
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Copyright (C) 2012 Theo Cushion
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
4
|
+
this software and associated documentation files (the "Software"), to deal in
|
5
|
+
the Software without restriction, including without limitation the rights to
|
6
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
7
|
+
of the Software, and to permit persons to whom the Software is furnished to do
|
8
|
+
so, subject to the following conditions:
|
9
|
+
|
10
|
+
The above copyright notice and this permission notice shall be included in all
|
11
|
+
copies or substantial portions of the Software.
|
12
|
+
|
13
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
Littleneck ClamAV [![Build status](https://secure.travis-ci.org/theozaurus/littleneck_clamav.png)](http://travis-ci.org/theozaurus/littleneck_clamav)
|
2
|
+
=================
|
3
|
+
|
4
|
+
[Littleneck ClamAV](http://github.com/theozaurus/littleneck_clamav) is a thin
|
5
|
+
wrapper to make it quick and easy to use [ClamAV](http://www.clamav.net) within
|
6
|
+
Ruby.
|
7
|
+
|
8
|
+
It will use `clamdscan` if available to save load time, or fallback to
|
9
|
+
`clamscan` if it is not. Compilation is avoided by using the command line
|
10
|
+
interface of ClamAV, and as such Littleneck expects a working and up to date
|
11
|
+
ClamAV installation.
|
12
|
+
|
13
|
+
Requirements
|
14
|
+
============
|
15
|
+
|
16
|
+
It is currently fully tested against:
|
17
|
+
|
18
|
+
- Ruby 1.9.3
|
19
|
+
|
20
|
+
Usage
|
21
|
+
=====
|
22
|
+
|
23
|
+
To scan a file:
|
24
|
+
|
25
|
+
scanner = LittleneckClamAV.new
|
26
|
+
result = scanner.scan "jeepers.txt"
|
27
|
+
result.clean?
|
28
|
+
=> false
|
29
|
+
result.infected?
|
30
|
+
=> true
|
31
|
+
result.description
|
32
|
+
=> "HLLP.Creeper.5127"
|
33
|
+
result.path
|
34
|
+
=> "jeepers.txt"
|
35
|
+
|
36
|
+
To find out about the scanners database
|
37
|
+
|
38
|
+
scanner.database_version
|
39
|
+
=> 15306
|
40
|
+
scanner.database_date
|
41
|
+
=> 2012-08-28 20:18:12 +00:00
|
42
|
+
scanner.engine
|
43
|
+
=> "0.97.5"
|
44
|
+
|
45
|
+
You can specify a specific scanner to use as well
|
46
|
+
|
47
|
+
scanner = LittleneckClamAV::Clam.new
|
48
|
+
# or
|
49
|
+
scanner = LittleneckClamAV::Clamd.new
|
50
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require "cocaine"
|
2
|
+
require "time"
|
3
|
+
|
4
|
+
require_relative "result"
|
5
|
+
require_relative "error"
|
6
|
+
|
7
|
+
class LittleneckClamAV
|
8
|
+
|
9
|
+
class Clam
|
10
|
+
|
11
|
+
def engine
|
12
|
+
version[:engine] if available?
|
13
|
+
end
|
14
|
+
|
15
|
+
def database_version
|
16
|
+
version[:database_version].to_i if available?
|
17
|
+
end
|
18
|
+
|
19
|
+
def database_date
|
20
|
+
Time.parse(version[:database_date]) if available?
|
21
|
+
end
|
22
|
+
|
23
|
+
def available?
|
24
|
+
version[:success]
|
25
|
+
end
|
26
|
+
|
27
|
+
def scan(path)
|
28
|
+
check_scan! path
|
29
|
+
opts = { :swallow_stderr => true, :expected_outcodes => [0, 1] }
|
30
|
+
params = ["--no-summary", path].join(" ")
|
31
|
+
output = Cocaine::CommandLine.new( command, params, opts ).run
|
32
|
+
parse_result path, output, $?.exitstatus
|
33
|
+
end
|
34
|
+
|
35
|
+
def command
|
36
|
+
"clamscan"
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def version
|
42
|
+
@version ||= begin
|
43
|
+
opts = { :swallow_stderr => true }
|
44
|
+
params = "--version"
|
45
|
+
output = Cocaine::CommandLine.new( command, params, opts ).run
|
46
|
+
output.strip!
|
47
|
+
engine, db_version, db_date = output.sub(/^ClamAV /,'').split("/",3)
|
48
|
+
success = !!(db_version && db_date)
|
49
|
+
{
|
50
|
+
:output => output,
|
51
|
+
:engine => engine,
|
52
|
+
:database_version => db_version,
|
53
|
+
:database_date => db_date,
|
54
|
+
:success => success
|
55
|
+
}
|
56
|
+
rescue Cocaine::ExitStatusError, Cocaine::CommandNotFoundError => e
|
57
|
+
{:error => e.message, :success => false }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def parse_result(path, output, code)
|
62
|
+
clean = $?.exitstatus == 0
|
63
|
+
description = output.split(":").last.strip
|
64
|
+
description.sub! " FOUND", ""
|
65
|
+
Result.new :path => path, :clean => clean, :description => description
|
66
|
+
end
|
67
|
+
|
68
|
+
def check_scan!(path)
|
69
|
+
exists = File.exists? path
|
70
|
+
if !exists
|
71
|
+
raise Error, "the path #{path} does not exist"
|
72
|
+
elsif !available?
|
73
|
+
message = "#{self.class} is not available"
|
74
|
+
message << "because #{version[:message]}" if version[:message]
|
75
|
+
raise Error, message
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class LittleneckClamAV
|
2
|
+
|
3
|
+
class Result
|
4
|
+
|
5
|
+
def initialize(opts)
|
6
|
+
@path = opts[:path]
|
7
|
+
@clean = opts[:clean]
|
8
|
+
@description = opts[:description]
|
9
|
+
end
|
10
|
+
|
11
|
+
def path
|
12
|
+
@path
|
13
|
+
end
|
14
|
+
|
15
|
+
def clean?
|
16
|
+
@clean
|
17
|
+
end
|
18
|
+
|
19
|
+
def infected?
|
20
|
+
!@clean
|
21
|
+
end
|
22
|
+
|
23
|
+
def description
|
24
|
+
@description
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require_relative "littleneck_clamav/clam"
|
2
|
+
require_relative "littleneck_clamav/clamd"
|
3
|
+
require_relative "littleneck_clamav/error"
|
4
|
+
|
5
|
+
class LittleneckClamAV
|
6
|
+
|
7
|
+
def engine
|
8
|
+
scanner.engine
|
9
|
+
end
|
10
|
+
|
11
|
+
def database_version
|
12
|
+
scanner.database_version
|
13
|
+
end
|
14
|
+
|
15
|
+
def database_date
|
16
|
+
scanner.database_date
|
17
|
+
end
|
18
|
+
|
19
|
+
def available?
|
20
|
+
!!scanner
|
21
|
+
end
|
22
|
+
|
23
|
+
def scan(*args)
|
24
|
+
scanner.scan(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def scanner
|
28
|
+
@scanner ||= begin
|
29
|
+
scanner = scanners.find{|s| s.available? }
|
30
|
+
raise Error, "no scanner available, is ClamAV installed?" unless scanner
|
31
|
+
scanner
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def preference
|
38
|
+
[Clamd, Clam]
|
39
|
+
end
|
40
|
+
|
41
|
+
def scanners
|
42
|
+
@scanners ||= preference.map(&:new)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
data/spec/clam_spec.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LittleneckClamAV::Clam do
|
4
|
+
|
5
|
+
it_behaves_like "a scanner"
|
6
|
+
|
7
|
+
describe "instance method" do
|
8
|
+
|
9
|
+
describe "command" do
|
10
|
+
|
11
|
+
it "should return clamdscan" do
|
12
|
+
subject.command.should == "clamscan"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/spec/clamd_spec.rb
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LittleneckClamAV do
|
4
|
+
|
5
|
+
describe "instance method" do
|
6
|
+
|
7
|
+
describe "engine" do
|
8
|
+
|
9
|
+
it "should call `engine` on the scanner" do
|
10
|
+
scanner = mock("scanner")
|
11
|
+
scanner.should_receive :engine
|
12
|
+
subject.stub( :scanner => scanner )
|
13
|
+
|
14
|
+
subject.engine
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "database_version" do
|
20
|
+
|
21
|
+
it "should call `database_version` on the scanner" do
|
22
|
+
scanner = mock("scanner")
|
23
|
+
scanner.should_receive :database_version
|
24
|
+
subject.stub( :scanner => scanner )
|
25
|
+
|
26
|
+
subject.database_version
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
describe "database_date" do
|
32
|
+
|
33
|
+
it "should call `database_date` on the scanner" do
|
34
|
+
scanner = mock("scanner")
|
35
|
+
scanner.should_receive :database_date
|
36
|
+
subject.stub( :scanner => scanner )
|
37
|
+
|
38
|
+
subject.database_date
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "available?" do
|
44
|
+
|
45
|
+
it "should return true if a scanner is available" do
|
46
|
+
subject.stub( :scanner => Object.new )
|
47
|
+
|
48
|
+
subject.available?.should == true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should return false if a scanner is not available" do
|
52
|
+
subject.stub( :scanner => nil )
|
53
|
+
|
54
|
+
subject.available?.should == false
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "scan" do
|
60
|
+
|
61
|
+
it "should call `scan` on the scanner" do
|
62
|
+
scanner = mock("scanner")
|
63
|
+
scanner.should_receive :scan
|
64
|
+
subject.stub( :scanner => scanner )
|
65
|
+
|
66
|
+
subject.scan
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "scanner" do
|
72
|
+
|
73
|
+
it "should return Clamd if available" do
|
74
|
+
LittleneckClamAV::Clamd.any_instance.stub(:available? => true)
|
75
|
+
|
76
|
+
subject.scanner.should be_a LittleneckClamAV::Clamd
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should return Clam if Clamd is not available" do
|
80
|
+
LittleneckClamAV::Clamd.any_instance.stub(:available? => false)
|
81
|
+
LittleneckClamAV::Clam.any_instance.stub(:available? => true)
|
82
|
+
|
83
|
+
subject.scanner.should be_a LittleneckClamAV::Clam
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should raise an error if neither are available" do
|
87
|
+
LittleneckClamAV::Clamd.any_instance.stub(:available? => false)
|
88
|
+
LittleneckClamAV::Clam.any_instance.stub(:available? => false)
|
89
|
+
|
90
|
+
lambda { subject.scanner }.should raise_error( LittleneckClamAV::Error )
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe LittleneckClamAV::Result do
|
4
|
+
|
5
|
+
describe "instance method" do
|
6
|
+
|
7
|
+
describe "infected?" do
|
8
|
+
|
9
|
+
it "should return true when infected" do
|
10
|
+
result = result_factory :clean => false
|
11
|
+
result.infected?.should be_true
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should return false when clean" do
|
15
|
+
result = result_factory :clean => true
|
16
|
+
result.infected?.should be_false
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
describe "clean?" do
|
22
|
+
|
23
|
+
it "should return true when clean" do
|
24
|
+
result = result_factory :clean => true
|
25
|
+
result.clean?.should be_true
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should return false when infected" do
|
29
|
+
result = result_factory :clean => false
|
30
|
+
result.clean?.should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "description" do
|
36
|
+
|
37
|
+
it "should return the description passed in" do
|
38
|
+
result = result_factory :description => "Hello"
|
39
|
+
result.description.should == "Hello"
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "path" do
|
45
|
+
|
46
|
+
it "should return the path passed in" do
|
47
|
+
result = result_factory :path => "foo/bar"
|
48
|
+
result.path.should == "foo/bar"
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(File.dirname(__FILE__)),'lib')
|
2
|
+
|
3
|
+
require "littleneck_clamav"
|
4
|
+
require "rspec/mocks/any_instance"
|
5
|
+
|
6
|
+
Dir[File.join(File.dirname(__FILE__),'support','*.rb')].each{|f| require f }
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.expect_with :rspec
|
10
|
+
config.mock_with :rspec
|
11
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
shared_examples_for "a scanner" do
|
2
|
+
|
3
|
+
def mock_cocaine(cocaine_options={})
|
4
|
+
options = { :output => "", :exitvalue => 0 }.merge( cocaine_options )
|
5
|
+
mock = Cocaine::CommandLine.should_receive( :new )
|
6
|
+
mock = mock.with(
|
7
|
+
options[:cmd], options[:opts], options[:params]
|
8
|
+
) if options[:cmd] || options[:opts] || options[:params]
|
9
|
+
|
10
|
+
if cocaine_options[:raise]
|
11
|
+
mock.and_raise cocaine_options[:raise]
|
12
|
+
else
|
13
|
+
mock.and_return(
|
14
|
+
double "cocaine command", :run => options[:output]
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
`true` if options[:exitvalue] == 0
|
19
|
+
`false` if options[:exitvalue] == 1
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "instance method" do
|
23
|
+
|
24
|
+
describe "engine" do
|
25
|
+
|
26
|
+
it "should call Cocaine with correct parameters" do
|
27
|
+
mock_cocaine :cmd => subject.command, :opts => "--version", :params => { :swallow_stderr => true }
|
28
|
+
subject.engine
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should interpret the return value correctly" do
|
32
|
+
mock_cocaine :output => "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
33
|
+
subject.engine.should == "0.97.5"
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "database_version" do
|
39
|
+
|
40
|
+
it "should call Cocaine with correct parameters" do
|
41
|
+
mock_cocaine :cmd => subject.command, :opts => "--version", :params => { :swallow_stderr => true }
|
42
|
+
subject.database_version
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should interpret the return value correctly" do
|
46
|
+
mock_cocaine :output => "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
47
|
+
subject.database_version.should == 15306
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "database_version" do
|
53
|
+
|
54
|
+
it "should call Cocaine with correct parameters" do
|
55
|
+
mock_cocaine :cmd => subject.command, :opts => "--version", :params => { :swallow_stderr => true }
|
56
|
+
subject.database_date
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should interpret the return value correctly" do
|
60
|
+
mock_cocaine :output => "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
61
|
+
subject.database_date.should == Time.parse("Tue Aug 28 20:18:12 2012")
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "available?" do
|
67
|
+
|
68
|
+
it "should return true when Cocaine returns okay" do
|
69
|
+
mock_cocaine :output => "ClamAV 0.97.5/15306/Tue Aug 28 20:18:12 2012\n"
|
70
|
+
|
71
|
+
subject.available?.should == true
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should return false when command errors" do
|
75
|
+
mock_cocaine :raise => Cocaine::ExitStatusError.new( "oh noes" )
|
76
|
+
|
77
|
+
subject.available?.should == false
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should return false when command is not found" do
|
81
|
+
mock_cocaine :raise => Cocaine::CommandNotFoundError
|
82
|
+
|
83
|
+
subject.available?.should == false
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
describe "scan" do
|
89
|
+
|
90
|
+
it "should call Cocaine" do
|
91
|
+
file = __FILE__
|
92
|
+
|
93
|
+
subject.stub(:available?).and_return(true)
|
94
|
+
|
95
|
+
mock_cocaine :cmd => subject.command,
|
96
|
+
:opts => "--no-summary #{file}",
|
97
|
+
:params => { :swallow_stderr => true, :expected_outcodes => [0, 1] },
|
98
|
+
:output => "#{file}: OK"
|
99
|
+
|
100
|
+
subject.scan file
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should create a Result" do
|
104
|
+
file = __FILE__
|
105
|
+
|
106
|
+
subject.stub(:available?).and_return(true)
|
107
|
+
|
108
|
+
mock_cocaine :output => "#{file}: OK\n"
|
109
|
+
|
110
|
+
LittleneckClamAV::Result.should_receive(:new).with(:path => file, :clean => true, :description => "OK")
|
111
|
+
|
112
|
+
subject.scan file
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should raise an error if the path does not exist" do
|
116
|
+
lambda { subject.scan "foo" }.should raise_error( LittleneckClamAV::Error )
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should raise an error if it is not available" do
|
120
|
+
file = __FILE__
|
121
|
+
|
122
|
+
subject.stub(:available?).and_return(false)
|
123
|
+
|
124
|
+
lambda { subject.scan "foo" }.should raise_error( LittleneckClamAV::Error )
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
130
|
+
|
131
|
+
end
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: littleneck_clamav
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Theo Cushion
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-09-11 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: cocaine
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rspec
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.11'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.11'
|
62
|
+
description:
|
63
|
+
email: theo.c@zepler.net
|
64
|
+
executables: []
|
65
|
+
extensions: []
|
66
|
+
extra_rdoc_files: []
|
67
|
+
files:
|
68
|
+
- lib/littleneck_clamav/clam.rb
|
69
|
+
- lib/littleneck_clamav/clamd.rb
|
70
|
+
- lib/littleneck_clamav/error.rb
|
71
|
+
- lib/littleneck_clamav/result.rb
|
72
|
+
- lib/littleneck_clamav.rb
|
73
|
+
- LICENSE
|
74
|
+
- README.md
|
75
|
+
- spec/clam_spec.rb
|
76
|
+
- spec/clamd_spec.rb
|
77
|
+
- spec/littleneck_clamav_spec.rb
|
78
|
+
- spec/result_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
- spec/support/factories.rb
|
81
|
+
- spec/support/shared_examples.rb
|
82
|
+
- .rspec
|
83
|
+
homepage: http://github.com/theozaurus/littleneck_clamav
|
84
|
+
licenses:
|
85
|
+
- MIT
|
86
|
+
post_install_message:
|
87
|
+
rdoc_options: []
|
88
|
+
require_paths:
|
89
|
+
- lib
|
90
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
92
|
+
requirements:
|
93
|
+
- - ! '>='
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
segments:
|
97
|
+
- 0
|
98
|
+
hash: -4199699967230361114
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
none: false
|
101
|
+
requirements:
|
102
|
+
- - ! '>='
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 1.3.6
|
105
|
+
requirements: []
|
106
|
+
rubyforge_project:
|
107
|
+
rubygems_version: 1.8.24
|
108
|
+
signing_key:
|
109
|
+
specification_version: 3
|
110
|
+
summary: A thin wrapper to make it quick and easy to use ClamAV (daemonised or not)
|
111
|
+
within Ruby
|
112
|
+
test_files:
|
113
|
+
- spec/clam_spec.rb
|
114
|
+
- spec/clamd_spec.rb
|
115
|
+
- spec/littleneck_clamav_spec.rb
|
116
|
+
- spec/result_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
- spec/support/factories.rb
|
119
|
+
- spec/support/shared_examples.rb
|
120
|
+
- .rspec
|