clamav-client 1.0.0 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: adce3820c1acb8ee407dfe43d13cc0fbff8871ca
4
- data.tar.gz: ba5be7eb98e86a26030a7da773f46c6abeb096a6
3
+ metadata.gz: 0e16bf843318d1ae3aec44e522c278143affc3d2
4
+ data.tar.gz: 100e606c288e5a6a3a46a0537e4d4f6f0d989b9c
5
5
  SHA512:
6
- metadata.gz: 9249db0df3fde3b800dfb47dae0aae73884f7d6db27a764bee4df9bb30dba67fba1cfe94098b863eafd999c78a1652c7a04f3b4f3b9ff40d58dc5f3475c96bb4
7
- data.tar.gz: fdde76cc4230eb0577f1637c9d5d1e72ff0a3e41bbcbc3f8e1e9d7939018f2ba90fe45f71252e8425419cd02a2fef2ff3dc8794bdea4addc71b6ba92bcbb6a6e
6
+ metadata.gz: 06d3e9d069ff7875b6f499c78adfbdaae9a29a030fd38f68435393e322cfa3c407c0d53a72d4067550cfa0b09c3da73858c4d944b8ce46f31c95ccb4d3484a0e
7
+ data.tar.gz: 141d5420ccd5fc6a90332b77184b5c1c593d2b27ce297a2b498677cc7b176a87aa3dffdd86f13173492912f47ed2906faba88daa17280407fbffb092d11df4a4
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.0
4
+ - 2.0.0
5
+ - 1.9.3
6
+ - 1.9.2
7
+ - ruby-head
8
+ - jruby-19mode
9
+ - jruby-head
10
+ - rbx
11
+ script: rake unit_tests
data/README.md CHANGED
@@ -22,7 +22,7 @@ Alternatively, you can spawn a `pry` console right away by just running:
22
22
 
23
23
  ## Requirements
24
24
 
25
- * Ruby >= 2 (and Ruby >= 2.1 to be able to contribute to the project as it's making use of required keyword arguments)
25
+ * Ruby >= 1.9.2
26
26
  * clamd
27
27
 
28
28
  ## Usage
@@ -30,15 +30,17 @@ Alternatively, you can spawn a `pry` console right away by just running:
30
30
  The `ClamAV::Client` class is responsible for opening a connection to a remote
31
31
  ClamAV clam daemon.
32
32
 
33
- You will find below the implemented commands.
33
+ See the implemented commands below.
34
34
 
35
35
  ### PING => Boolean
36
36
 
37
37
  Pings the daemon to check whether it is alive.
38
38
 
39
- client = ClamAV::Client.new
40
- client.execute(ClamAV::Commands::PingCommand.new)
41
- => true
39
+ ```ruby
40
+ client = ClamAV::Client.new
41
+ client.execute(ClamAV::Commands::PingCommand.new)
42
+ # => true
43
+ ```
42
44
 
43
45
  ### SCAN <file_or_directory> => Array[Response]
44
46
 
@@ -46,56 +48,73 @@ Scans a file or a directory for the existence of a virus.
46
48
 
47
49
  The absolute path must be given to that command.
48
50
 
49
- client = ClamAV::Client.new
51
+ ```ruby
52
+ client = ClamAV::Client.new
50
53
 
51
- client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path/foo.c')
52
- => [#<ClamAV::SuccessResponse:0x007fbf314b9478 @file="/tmp/foo.c">]
54
+ client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path/foo.c'))
55
+ # => [#<ClamAV::SuccessResponse:0x007fbf314b9478 @file="/tmp/foo.c">]
53
56
 
54
- client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path')
55
- => [#<ClamAV::SuccessResponse:0x007fc30c273298 @file="/tmp/path/foo.c">,
56
- #<ClamAV::SuccessResponse:0x007fc30c272910 @file="/tmp/path/foo.cpp">]
57
+ client.execute(ClamAV::Commands::ScanCommand.new('/tmp/path'))
58
+ # => [#<ClamAV::SuccessResponse:0x007fc30c273298 @file="/tmp/path/foo.c">,
59
+ # #<ClamAV::SuccessResponse:0x007fc30c272910 @file="/tmp/path/foo.cpp">]
60
+ ```
57
61
 
62
+ ### INSTREAM => Response
63
+
64
+ Scans an IO-like object for the existence of a virus.
65
+
66
+ ```ruby
67
+ client = ClamAV::Client.new
68
+
69
+ io = StringIO.new('some data')
70
+ client.execute(ClamAV::Commands::InstreamCommand.new(io))
71
+ # => [#<ClamAV::SuccessResponse:0x007fe471cabe50 @file="stream">]
72
+ ```
58
73
 
59
74
  ### Custom commands
60
75
 
61
76
  Custom commands can be given to the client. The contract between the client
62
- and the command is thru the `call` method call. The `call` method is being
63
- passed a `Connection` object.
64
-
65
- Here's a simple example that implements the `VERSION` command:
77
+ and the command is through the `Command#call` method. The `call` method will
78
+ receive a `Connection` object.
66
79
 
67
- # Build the client
68
- client = ClamAV::Client.new
80
+ Here's a simple example implementing the `VERSION` command:
69
81
 
70
- # Create the command lambda
71
- version_command = lambda { |conn| conn.send_request("VERSION") }
72
- => #<Proc:0x007fc0d0c14b28>
82
+ ```ruby
83
+ # Build the client
84
+ client = ClamAV::Client.new
73
85
 
74
- # Execute the command
75
- client.execute(version_command)
76
- => "1: ClamAV 0.98.1/18489/Tue Feb 18 16:00:05 2014"
86
+ # Create the command lambda
87
+ version_command = lambda { |conn| conn.send_request("VERSION") }
88
+ # => #<Proc:0x007fc0d0c14b28>
77
89
 
90
+ # Execute the command
91
+ client.execute(version_command)
92
+ # => "1: ClamAV 0.98.1/18489/Tue Feb 18 16:00:05 2014"
93
+ ```
78
94
 
79
95
  ## Defaults
80
96
 
81
97
  The default values in use are:
82
98
 
83
- * clamd socket: UNIX Socket, located at `/tmp/clamd/socket`;
99
+ * clamd socket: UNIX Socket, located at `/var/run/clamav/clamd.ctl`;
84
100
  * New-line terminated commands.
85
101
 
86
- These defaults can be changed by injecting new defaults.
102
+ These defaults can be changed:
87
103
 
88
- ## Injecting dependencies
104
+ * by creating the object graph manually;
105
+ * by setting environment variables.
89
106
 
90
- ### Client
107
+ ### The object graph
108
+
109
+ #### Client
91
110
 
92
111
  The main object is the `Client` object. It is responsible for executing the commands.
93
- This object can receive a custom connection object.
112
+ It can receive a custom connection object.
94
113
 
95
- ### Connection
114
+ #### Connection
96
115
 
97
- The connection object is the bridge between the raw socket object and the
98
- protocol being used between the client and the daemon.
116
+ The `Connection` object is the bridge between the raw socket object and the
117
+ protocol used between the client and the daemon.
99
118
 
100
119
  `clamd` supports two kinds of delimiters:
101
120
 
@@ -104,12 +123,43 @@ protocol being used between the client and the daemon.
104
123
 
105
124
  The management of those delimiters is done with the wrapper argument.
106
125
 
107
- ### Wrapper
126
+ #### Wrapper
108
127
 
109
128
  The wrapper is responsible for taking the incoming request with the
110
129
  `wrap_request` method, and parsing the response with the `read_response`
111
130
  method.
112
131
 
132
+ ### Environment variables
133
+
134
+ The variables can be set programmatically in your Ruby programs like
135
+
136
+ ```ruby
137
+ # from a ruby script
138
+ ENV['CLAMD_UNIX_SOCKET'] = '/some/path'
139
+
140
+ # Now the defaults are changed for any new ClamAV::Client instantiation
141
+ ```
142
+
143
+ or by setting the variables before starting the Ruby process:
144
+
145
+ ```
146
+ # from the command-line
147
+ export CLAMD_UNIX_SOCKET = '/some/path'
148
+ ruby my_program.rb
149
+ # or
150
+ CLAMD_UNIX_SOCKET = '/some/path' ruby my_program.rb
151
+ ```
152
+
153
+ Please note that setting the `CLAMD_TCP_*` variables will have the precedence
154
+ over the `CLAMD_UNIX_SOCKET`.
155
+
156
+ #### CLAMD_UNIX_SOCKET
157
+
158
+ Sets the socket path of the ClamAV daemon.
159
+
160
+ #### CLAMD_TCP_HOST and CLAMD_TCP_PORT
161
+
162
+ Sets the host and port of the ClamAV daemon.
113
163
 
114
164
  ## Contributing
115
165
 
@@ -3,7 +3,7 @@ $:<< 'lib'
3
3
 
4
4
  Gem::Specification.new do |spec|
5
5
  spec.name = "clamav-client"
6
- spec.version = "1.0.0"
6
+ spec.version = "2.0.1"
7
7
  spec.authors = ["Franck Verrot"]
8
8
  spec.email = ["franck@verrot.fr"]
9
9
  spec.summary = %q{ClamAV::Client connects to a Clam Anti-Virus clam daemon and send commands.}
@@ -19,4 +19,5 @@ Gem::Specification.new do |spec|
19
19
  spec.add_development_dependency "bundler", "~> 1.5"
20
20
  spec.add_development_dependency "rake"
21
21
  spec.add_development_dependency "pry"
22
+ spec.add_development_dependency "minitest"
22
23
  end
@@ -18,6 +18,7 @@ require "clamav/connection"
18
18
  require "clamav/commands/ping_command"
19
19
  require "clamav/commands/quit_command"
20
20
  require "clamav/commands/scan_command"
21
+ require "clamav/commands/instream_command"
21
22
  require "clamav/util"
22
23
  require "clamav/wrappers/new_line_wrapper"
23
24
  require "clamav/wrappers/null_termination_wrapper"
@@ -30,14 +31,23 @@ module ClamAV
30
31
  end
31
32
 
32
33
  def execute(command)
33
- command.(@connection)
34
+ command.call(@connection)
34
35
  end
35
36
 
36
37
  def default_connection
37
38
  ClamAV::Connection.new(
38
- socket: ::UNIXSocket.new('/tmp/clamd.socket'),
39
+ socket: resolve_default_socket,
39
40
  wrapper: ::ClamAV::Wrappers::NewLineWrapper.new
40
41
  )
41
42
  end
43
+
44
+ def resolve_default_socket
45
+ unix_socket, tcp_host, tcp_port = ENV.values_at('CLAMD_UNIX_SOCKET', 'CLAMD_TCP_HOST', 'CLAMD_TCP_PORT')
46
+ if tcp_host && tcp_port
47
+ ::TCPSocket.new(tcp_host, tcp_port)
48
+ else
49
+ ::UNIXSocket.new(unix_socket || '/var/run/clamav/clamd.ctl')
50
+ end
51
+ end
42
52
  end
43
53
  end
@@ -13,20 +13,34 @@
13
13
 
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require 'clamav/responses/error_response'
18
+ require 'clamav/responses/success_response'
19
+ require 'clamav/responses/virus_response'
20
+
16
21
  module ClamAV
17
22
  module Commands
18
23
  class Command
19
- def call
20
- raise NotImplementedError.new
21
- end
24
+ Statuses = {
25
+ 'OK' => ClamAV::SuccessResponse,
26
+ 'ERROR' => ClamAV::ErrorResponse,
27
+ 'ClamAV-Test-Signature FOUND' => ClamAV::VirusResponse
28
+ }
29
+
30
+ def call; raise NotImplementedError.new; end
22
31
 
23
32
  protected
24
- def execute
25
- conn.puts data + "\n"
26
- response = conn.gets.chomp
27
- conn.close
28
- response
29
- end
33
+
34
+ def get_status_from_response(str)
35
+ case str
36
+ when 'Error processing command. ERROR'
37
+ ErrorResponse.new(str)
38
+ else
39
+ /(?<id>\d+): (?<filepath>.*): (?<status>.*)/ =~ str
40
+ Statuses[status].new(filepath)
41
+ end
42
+ end
43
+
30
44
  end
31
45
  end
32
46
  end
@@ -0,0 +1,41 @@
1
+ # clamav-client - ClamAV client
2
+ # Copyright (C) 2014 Franck Verrot <franck@verrot.fr>
3
+
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require 'clamav/commands/command'
18
+
19
+ module ClamAV
20
+ module Commands
21
+ class InstreamCommand < Command
22
+
23
+ def initialize(io, max_chunk_size = 1024)
24
+ @io = begin io rescue raise ArgumentError, 'io is required', caller; end
25
+ @max_chunk_size = max_chunk_size
26
+ end
27
+
28
+ def call(conn)
29
+ conn.write_request("INSTREAM")
30
+
31
+ while(packet = @io.read(@max_chunk_size))
32
+ packet_size = [packet.size].pack("N")
33
+ conn.raw_write("#{packet_size}#{packet}")
34
+ end
35
+ conn.raw_write("\x00\x00\x00\x00")
36
+ get_status_from_response(conn.read_response)
37
+ end
38
+
39
+ end
40
+ end
41
+ end
@@ -15,17 +15,10 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'clamav/commands/command'
18
- require 'clamav/responses/error_response'
19
- require 'clamav/responses/success_response'
20
- require 'clamav/responses/virus_response'
18
+
21
19
  module ClamAV
22
20
  module Commands
23
21
  class ScanCommand < Command
24
- Statuses = {
25
- 'ERROR' => ClamAV::ErrorResponse,
26
- 'OK' => ClamAV::SuccessResponse,
27
- 'ClamAV-Test-Signature FOUND' => ClamAV::VirusResponse
28
- }
29
22
 
30
23
  def initialize(path, path_finder = Util)
31
24
  @path, @path_finder = path, path_finder
@@ -35,20 +28,10 @@ module ClamAV
35
28
  @path_finder.path_to_files(@path).map { |file| scan_file(conn, file) }
36
29
  end
37
30
 
38
- protected
39
31
  def scan_file(conn, file)
40
32
  get_status_from_response(conn.send_request("SCAN #{file}"))
41
33
  end
42
34
 
43
- def get_status_from_response(str)
44
- case str
45
- when 'Error processing command. ERROR'
46
- ErrorResponse.new(str)
47
- else
48
- /(?<id>\d+): (?<filepath>.*): (?<status>.*)/ =~ str
49
- Statuses[status].new(filepath)
50
- end
51
- end
52
35
  end
53
36
  end
54
37
  end
@@ -18,9 +18,16 @@ require 'socket'
18
18
 
19
19
  module ClamAV
20
20
  class Connection
21
- def initialize(socket:, wrapper:)
22
- @socket = socket
23
- @wrapper = wrapper
21
+ def initialize(args)
22
+ socket = args.fetch(:socket) { missing_required_argument(:socket) }
23
+ wrapper = args.fetch(:wrapper) { missing_required_argument(:wrapper) }
24
+
25
+ if socket && wrapper
26
+ @socket = socket
27
+ @wrapper = wrapper
28
+ else
29
+ raise ArgumentError
30
+ end
24
31
  end
25
32
 
26
33
  def establish_connection
@@ -28,10 +35,27 @@ module ClamAV
28
35
  @socket.write wrapped_request
29
36
  end
30
37
 
31
- def send_request(str)
38
+ def write_request(str)
32
39
  wrapped_request = @wrapper.wrap_request(str)
33
40
  @socket.write wrapped_request
41
+ end
42
+
43
+ def read_response
34
44
  @wrapper.read_response(@socket)
35
45
  end
46
+
47
+ def send_request(str)
48
+ write_request(str)
49
+ read_response
50
+ end
51
+
52
+ def raw_write(str)
53
+ @socket.write str
54
+ end
55
+
56
+ private
57
+ def missing_required_argument(key)
58
+ raise ArgumentError, "#{key} is required"
59
+ end
36
60
  end
37
61
  end
@@ -21,10 +21,12 @@ module ClamAV
21
21
  end
22
22
 
23
23
  def ==(other)
24
- @file == other.file
24
+ @file == other.file && self.class == other.class
25
25
  end
26
26
 
27
27
  protected
28
+
28
29
  attr_reader :file
30
+
29
31
  end
30
32
  end
@@ -15,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'clamav/responses'
18
+
18
19
  module ClamAV
19
20
  class ErrorResponse < Response
20
21
  end
@@ -15,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'clamav/responses'
18
+
18
19
  module ClamAV
19
20
  class SuccessResponse < Response
20
21
  end
@@ -15,6 +15,7 @@
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
17
  require 'clamav/responses'
18
+
18
19
  module ClamAV
19
20
  class VirusResponse < Response
20
21
  end
@@ -18,5 +18,14 @@ module ClamAV
18
18
  class Wrapper
19
19
  def wrap_request(request); raise NotImplementedError; end
20
20
  def unwrap_response(response); raise NotImplementedError; end
21
+
22
+ protected
23
+ def read_until(socket, delimiter)
24
+ buff = ""
25
+ while (char = socket.getc) != delimiter
26
+ buff << char
27
+ end
28
+ buff
29
+ end
21
30
  end
22
31
  end
@@ -24,11 +24,7 @@ module ClamAV
24
24
  end
25
25
 
26
26
  def read_response(socket)
27
- buff = ""
28
- while (char = socket.getc) != "\n"
29
- buff << char
30
- end
31
- buff
27
+ read_until(socket, "\n")
32
28
  end
33
29
  end
34
30
  end
@@ -24,11 +24,7 @@ module ClamAV
24
24
  end
25
25
 
26
26
  def read_response(socket)
27
- buff = ""
28
- while (char = socket.getc) != "\0"
29
- buff << char
30
- end
31
- buff
27
+ read_until(socket, "\0")
32
28
  end
33
29
  end
34
30
  end
@@ -53,5 +53,20 @@ describe "ClamAV::Client Integration Tests" do
53
53
  assert_equal expected_results, results
54
54
  end
55
55
  end
56
+
57
+ describe "instream" do
58
+ it "can be started" do
59
+ dir = File.expand_path('../../../../test/fixtures', __FILE__)
60
+
61
+ [
62
+ ['clamavtest.txt', ClamAV::VirusResponse],
63
+ ['innocent.txt', ClamAV::SuccessResponse]
64
+ ].each do |file, response_class|
65
+ io = File.open(File.join(dir, file))
66
+ command = ClamAV::Commands::InstreamCommand.new(io)
67
+ client.execute(command).must_equal response_class.new("stream")
68
+ end
69
+ end
70
+ end
56
71
  end
57
72
  end
@@ -14,6 +14,8 @@
14
14
  # You should have received a copy of the GNU General Public License
15
15
  # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
 
17
- require 'minitest/autorun'
17
+ gem 'minitest'
18
18
 
19
+ require 'minitest/autorun'
19
20
  require 'clamav/client'
21
+ require 'pry'
@@ -0,0 +1,53 @@
1
+ # clamav-client - ClamAV client
2
+ # Copyright (C) 2014 Franck Verrot <franck@verrot.fr>
3
+
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation, either version 3 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details.
13
+
14
+ # You should have received a copy of the GNU General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require 'test_helper'
18
+
19
+ describe "INSTREAM command" do
20
+ before do
21
+ @conn = Minitest::Mock.new
22
+ @io = ::StringIO.new('hello')
23
+ end
24
+
25
+ after do
26
+ @conn.verify
27
+ end
28
+
29
+ it "can process an IO object" do
30
+ @conn.expect(:write_request, nil, ["INSTREAM"])
31
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x05hello"])
32
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x00"])
33
+ @conn.expect(:read_response, '1: stream: OK', [])
34
+
35
+ assert ClamAV::Commands::InstreamCommand.new(@io).call(@conn)
36
+ end
37
+
38
+ it "can specify the size of read chunks" do
39
+ chunk_size = 1
40
+
41
+ @conn.expect(:write_request, nil, ["INSTREAM"])
42
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x01h"])
43
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x01e"])
44
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x01l"])
45
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x01l"])
46
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x01o"])
47
+ @conn.expect(:raw_write, nil, ["\x00\x00\x00\x00"])
48
+ @conn.expect(:read_response, '1: stream: OK', [])
49
+
50
+ assert ClamAV::Commands::InstreamCommand.
51
+ new(@io, chunk_size).call(@conn)
52
+ end
53
+ end
@@ -18,7 +18,7 @@ require 'test_helper'
18
18
 
19
19
  describe "ClamAV::Connection" do
20
20
  let(:wrapper_mock) { Minitest::Mock.new }
21
- let(:socket_mock) { Minitest::Mock.new }
21
+ let(:socket_mock) { Minitest::Mock.new }
22
22
 
23
23
  it "requires a port and a wrapper" do
24
24
  assert_raises(ArgumentError) { ClamAV::Connection.new }
@@ -29,4 +29,11 @@ describe "ClamAV::Connection" do
29
29
  it "can be constructed with a port and wrapper class" do
30
30
  ClamAV::Connection.new(socket: socket_mock, wrapper: wrapper_mock)
31
31
  end
32
+
33
+ it "support raw writes" do
34
+ socket_mock.expect(:write, nil, ["foo"])
35
+
36
+ conn = ClamAV::Connection.new(socket: socket_mock, wrapper: wrapper_mock)
37
+ conn.raw_write("foo")
38
+ end
32
39
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clamav-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franck Verrot
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-20 00:00:00.000000000 Z
11
+ date: 2014-02-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  description: ClamAV::Client connects to a Clam Anti-Virus clam daemon and send commands.
56
70
  email:
57
71
  - franck@verrot.fr
@@ -60,6 +74,7 @@ extensions: []
60
74
  extra_rdoc_files: []
61
75
  files:
62
76
  - ".gitignore"
77
+ - ".travis.yml"
63
78
  - Gemfile
64
79
  - LICENSE.txt
65
80
  - README.md
@@ -67,6 +82,7 @@ files:
67
82
  - clamav-client.gemspec
68
83
  - lib/clamav/client.rb
69
84
  - lib/clamav/commands/command.rb
85
+ - lib/clamav/commands/instream_command.rb
70
86
  - lib/clamav/commands/ping_command.rb
71
87
  - lib/clamav/commands/quit_command.rb
72
88
  - lib/clamav/commands/scan_command.rb
@@ -87,6 +103,7 @@ files:
87
103
  - test/integration/clamav/util_test.rb
88
104
  - test/test_helper.rb
89
105
  - test/unit/clamav/client_test.rb
106
+ - test/unit/clamav/commands/instream_command_test.rb
90
107
  - test/unit/clamav/commands/ping_command_test.rb
91
108
  - test/unit/clamav/commands/scan_command_test.rb
92
109
  - test/unit/clamav/connection_test.rb
@@ -125,6 +142,7 @@ test_files:
125
142
  - test/integration/clamav/util_test.rb
126
143
  - test/test_helper.rb
127
144
  - test/unit/clamav/client_test.rb
145
+ - test/unit/clamav/commands/instream_command_test.rb
128
146
  - test/unit/clamav/commands/ping_command_test.rb
129
147
  - test/unit/clamav/commands/scan_command_test.rb
130
148
  - test/unit/clamav/connection_test.rb