smb-client 0.1.1 → 0.1.2
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 +4 -4
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile.lock +9 -1
- data/README.md +26 -6
- data/lib/smb/client/client.rb +15 -4
- data/lib/smb/client/client_helper.rb +49 -30
- data/lib/smb/client/ls_item.rb +35 -0
- data/lib/smb/client/version.rb +1 -1
- data/smb-client.gemspec +1 -0
- metadata +17 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3f651dd31ee5d350f7e0b360cf174e194ae9bfab
|
4
|
+
data.tar.gz: b45cb7eb1f73c605139795bc71355ed75d04f8c1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9777debb5d8176ab01f543f8c37c8ffde3c9a6c5418745690ff927a1d2254ef826474c396144fe0ac2840958912a4cf00b7b6be54ea305d343bcdc2cc7c20b6e
|
7
|
+
data.tar.gz: 913a1a40edd78e053effd7cff12fe46a92b6ab7b061bbbc9dba19623bf158efde5bfe170a3b7fe9b9756cb39786fb2d801eaaf68f4e99e232461d376de066429
|
data/CODE_OF_CONDUCT.md
CHANGED
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
|
|
55
55
|
## Enforcement
|
56
56
|
|
57
57
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
-
reported by contacting the project team at ralf@
|
58
|
+
reported by contacting the project team at ralf.herzog@netcom-kassel.de. All
|
59
59
|
complaints will be reviewed and investigated and will result in a response that
|
60
60
|
is deemed necessary and appropriate to the circumstances. The project team is
|
61
61
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
data/Gemfile.lock
CHANGED
@@ -1,13 +1,20 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
smb-client (0.1.
|
4
|
+
smb-client (0.1.1)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
docile (1.1.5)
|
10
|
+
json (2.1.0)
|
9
11
|
minitest (5.10.3)
|
10
12
|
rake (10.5.0)
|
13
|
+
simplecov (0.15.1)
|
14
|
+
docile (~> 1.1.0)
|
15
|
+
json (>= 1.8, < 3)
|
16
|
+
simplecov-html (~> 0.10.0)
|
17
|
+
simplecov-html (0.10.2)
|
11
18
|
|
12
19
|
PLATFORMS
|
13
20
|
ruby
|
@@ -16,6 +23,7 @@ DEPENDENCIES
|
|
16
23
|
bundler (~> 1.16)
|
17
24
|
minitest (~> 5.0)
|
18
25
|
rake (~> 10.0)
|
26
|
+
simplecov
|
19
27
|
smb-client!
|
20
28
|
|
21
29
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -16,16 +16,18 @@ gem 'smb/client'
|
|
16
16
|
|
17
17
|
And then execute:
|
18
18
|
|
19
|
-
|
19
|
+
```bash
|
20
|
+
$ bundler install
|
21
|
+
```
|
20
22
|
|
21
23
|
Or install it yourself as:
|
22
24
|
|
23
|
-
|
25
|
+
```bash
|
26
|
+
$ gem install smb-client
|
27
|
+
```
|
24
28
|
|
25
29
|
## Usage
|
26
30
|
|
27
|
-
### Setup
|
28
|
-
|
29
31
|
```ruby
|
30
32
|
require 'smb/client'
|
31
33
|
|
@@ -42,7 +44,7 @@ options = {
|
|
42
44
|
|
43
45
|
### List directories
|
44
46
|
|
45
|
-
Always returns an array
|
47
|
+
Always returns an array containing `LsItem` elements.
|
46
48
|
|
47
49
|
```ruby
|
48
50
|
@smb_client.ls
|
@@ -75,6 +77,24 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
|
75
77
|
|
76
78
|
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
77
79
|
|
80
|
+
### Setup a SMB server for tests
|
81
|
+
|
82
|
+
For example with docker:
|
83
|
+
```bash
|
84
|
+
$ docker run -d -t --name samba -v /mount -d dperson/samba -u "guest1;pass1" -s "guest1_private;/mount;no;no;no;guest1" -w WORKGROUP
|
85
|
+
$ docker exec samba chmod 777 /mount
|
86
|
+
```
|
87
|
+
|
88
|
+
To get the container ip address run:
|
89
|
+
|
90
|
+
```bash
|
91
|
+
$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' samba
|
92
|
+
```
|
93
|
+
|
94
|
+
This returns for example: `172.17.0.2`
|
95
|
+
|
96
|
+
Now set the IP in the [test_helper.rb](https://github.com/NetcomKassel/smb-client/blob/master/test/test_helper.rb)'s `SMB_CLIENT_OPTIONS` hash.
|
97
|
+
|
78
98
|
## Contributing
|
79
99
|
|
80
100
|
Bug reports and pull requests are welcome on GitHub at https://github.com/NetcomKassel/smb-client. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
@@ -85,4 +105,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
85
105
|
|
86
106
|
## Code of Conduct
|
87
107
|
|
88
|
-
Everyone interacting in the SMB::Client project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
108
|
+
Everyone interacting in the SMB::Client project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/NetcomKassel/smb-client/blob/master/CODE_OF_CONDUCT.md).
|
data/lib/smb/client/client.rb
CHANGED
@@ -8,11 +8,14 @@ require_relative 'client_helper'
|
|
8
8
|
require_relative 'runtime_error'
|
9
9
|
|
10
10
|
module SMB
|
11
|
+
# Low-level interface to smbclient executable
|
11
12
|
class Client
|
12
13
|
include ClientHelper
|
13
14
|
|
14
15
|
attr_accessor :executable, :pid
|
15
16
|
|
17
|
+
# Creates a new instance and connects to server
|
18
|
+
# @param [Hash] options Hash with connection options
|
16
19
|
def initialize(options = {})
|
17
20
|
@executable = ENV.fetch('SMBCLIENT_EXECUTABLE') { 'smbclient' }
|
18
21
|
@options = {
|
@@ -40,11 +43,14 @@ module SMB
|
|
40
43
|
@shutdown_in_progress = false
|
41
44
|
end
|
42
45
|
|
46
|
+
# Closes the connection to the server end terminates all running threads
|
43
47
|
def close
|
44
48
|
@shutdown_in_progress = true
|
45
49
|
Process.kill('QUIT', @pid) == 1
|
46
50
|
end
|
47
51
|
|
52
|
+
# Execute a smbclient command
|
53
|
+
# @param [String] cmd The command to be executed
|
48
54
|
def exec(cmd)
|
49
55
|
# Send command
|
50
56
|
@write1.puts cmd
|
@@ -66,8 +72,9 @@ module SMB
|
|
66
72
|
|
67
73
|
private
|
68
74
|
|
75
|
+
# Connect to the server using separate threads and pipe for communications
|
69
76
|
def connect
|
70
|
-
# Run +@executable+ in a separate thread to talk to hin
|
77
|
+
# Run +@executable+ in a separate thread to talk to hin asynchronously
|
71
78
|
Thread.start do
|
72
79
|
# Spawn the actual +@executable+ pty with +input+ and +output+ handle
|
73
80
|
begin
|
@@ -83,8 +90,6 @@ module SMB
|
|
83
90
|
end
|
84
91
|
end
|
85
92
|
|
86
|
-
@connection_established = true
|
87
|
-
|
88
93
|
# Wait for responses ending with input prompt
|
89
94
|
loop do
|
90
95
|
output.expect(/smb: \\>$/) { |text| handle_response text }
|
@@ -102,6 +107,8 @@ module SMB
|
|
102
107
|
end
|
103
108
|
end
|
104
109
|
|
110
|
+
# Returns the parameters for the +smbclient+ command
|
111
|
+
# @return [String] The parameters
|
105
112
|
def params
|
106
113
|
@options.map do |k, v|
|
107
114
|
v.nil? && raise(Client::RuntimeError, "Missing option [:#{k}]")
|
@@ -110,17 +117,21 @@ module SMB
|
|
110
117
|
-U #{@options[:user]} #{@options[:workgroup]} -m SMB#{@options[:version]}"
|
111
118
|
end
|
112
119
|
|
120
|
+
# Handles a response from smbclient
|
113
121
|
def handle_response(text)
|
114
122
|
# Write to second pipe so the origin command invocation thread can
|
115
123
|
# receive this
|
116
124
|
if @first_message
|
117
125
|
@first_message = false
|
126
|
+
# TODO: Filter for server information? => Domain, OS and Server
|
127
|
+
|
128
|
+
@connection_established = true
|
118
129
|
return
|
119
130
|
end
|
120
131
|
|
121
132
|
# Format responses
|
122
133
|
# Ignore command sent (the first returned line) and the last returned
|
123
|
-
# which is the smb prompt
|
134
|
+
# which is the smb prompt ("smb: \>")
|
124
135
|
@write2.write text[0].lines[1..-2].join
|
125
136
|
@write2.close
|
126
137
|
end
|
@@ -1,38 +1,16 @@
|
|
1
1
|
require 'time'
|
2
2
|
require 'tempfile'
|
3
3
|
|
4
|
+
require_relative 'ls_item'
|
5
|
+
|
4
6
|
module SMB
|
7
|
+
# Helper methods to get simpler access to smbclient's capabilities
|
5
8
|
module ClientHelper
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
def file?
|
12
|
-
@type.include? 'N'
|
13
|
-
end
|
14
|
-
|
15
|
-
def directory?
|
16
|
-
@type.include? 'D'
|
17
|
-
end
|
18
|
-
|
19
|
-
def hidden?
|
20
|
-
@type.include? 'H'
|
21
|
-
end
|
22
|
-
|
23
|
-
def self.from_line(line)
|
24
|
-
match_data = REGEX.match line
|
25
|
-
return nil unless match_data
|
26
|
-
|
27
|
-
item = LsItem.new
|
28
|
-
item.name = match_data['name']
|
29
|
-
item.type = match_data['type']
|
30
|
-
item.size = match_data['size'].to_i
|
31
|
-
item.change_time = Time.parse match_data['change_time']
|
32
|
-
item
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
9
|
+
# List contents of a remote directory
|
10
|
+
# @param [String] mask The matching mask
|
11
|
+
# @param [Boolean] raise If set, an error will be raised. If set to
|
12
|
+
# +false+, an empty array will be returned
|
13
|
+
# @return [Array] List of +mask+ matching LsItems
|
36
14
|
def ls(mask = '', raise = true)
|
37
15
|
ls_items = []
|
38
16
|
output = exec 'ls ' + mask
|
@@ -46,8 +24,13 @@ module SMB
|
|
46
24
|
[]
|
47
25
|
end
|
48
26
|
|
27
|
+
# +dir+ is an alias for +ls+
|
49
28
|
alias dir ls
|
50
29
|
|
30
|
+
# Creates a new directory on the server
|
31
|
+
# @param [String] path The path to be created
|
32
|
+
# @param [Boolean] raise raise Error or just return +false+
|
33
|
+
# @return [Boolean] true on success
|
51
34
|
def mkdir(path, raise = true)
|
52
35
|
exec 'mkdir ' + path
|
53
36
|
true
|
@@ -56,6 +39,10 @@ module SMB
|
|
56
39
|
false
|
57
40
|
end
|
58
41
|
|
42
|
+
# Removes a directory on the server
|
43
|
+
# @param [String] path The path to be removed
|
44
|
+
# @param [TrueClass/FalseClass] raise raise Error or just return +false+
|
45
|
+
# @return [Boolean] true on success
|
59
46
|
def rmdir(path, raise = true)
|
60
47
|
exec 'rmdir ' + path
|
61
48
|
true
|
@@ -64,6 +51,12 @@ module SMB
|
|
64
51
|
false
|
65
52
|
end
|
66
53
|
|
54
|
+
# Upload a local file
|
55
|
+
# @param [String] from The source file path (on local machine)
|
56
|
+
# @param [String] to The destination file path
|
57
|
+
# @param [Boolean] overwrite Overwrite if exist on server?
|
58
|
+
# @param [Boolean] raise raise Error or just return +false+
|
59
|
+
# @return [Boolean] true on success
|
67
60
|
def put(from, to, overwrite = false, raise = true)
|
68
61
|
ls_items = ls to, false
|
69
62
|
if !overwrite && !ls_items.empty?
|
@@ -76,7 +69,14 @@ module SMB
|
|
76
69
|
false
|
77
70
|
end
|
78
71
|
|
72
|
+
# Writes content to remote file
|
73
|
+
# @param [String] content The content to be written
|
74
|
+
# @param [String] to The destination file path
|
75
|
+
# @param [Boolean] overwrite Overwrite if exist on server?
|
76
|
+
# @param [Boolean] raise raise Error or just return +false+
|
77
|
+
# @return [Boolean] true on success
|
79
78
|
def write(content, to, overwrite = false, raise = true)
|
79
|
+
# This is just a hack around +put+
|
80
80
|
tempfile = Tempfile.new
|
81
81
|
tempfile.write content
|
82
82
|
tempfile.close
|
@@ -84,6 +84,10 @@ module SMB
|
|
84
84
|
put tempfile.path, to, overwrite, raise
|
85
85
|
end
|
86
86
|
|
87
|
+
# Delete a remote file
|
88
|
+
# @param [String] path The remote file to be deleted
|
89
|
+
# @param [Boolean] raise raise raise Error or just return +false+
|
90
|
+
# @return [Boolean] true on success
|
87
91
|
def del(path, raise = true)
|
88
92
|
exec 'del ' + path
|
89
93
|
true
|
@@ -92,12 +96,22 @@ module SMB
|
|
92
96
|
false
|
93
97
|
end
|
94
98
|
|
99
|
+
# +rm+ is an alias for +del+
|
95
100
|
alias rm del
|
96
101
|
|
102
|
+
# Receive a file from the smb server to local.
|
103
|
+
# If +to+ was not passed, a tempfile will be generated.
|
104
|
+
# @param [String] from The remote file to be read
|
105
|
+
# @param [String] to local file path to be created
|
106
|
+
# @param [Boolean] overwrite Overwrite if exist locally?
|
107
|
+
# @param [Boolean] raise raise Error or just return +false+
|
97
108
|
def get(from, to = nil, overwrite = false, raise = true)
|
109
|
+
# Create a new tempfile but delete it
|
110
|
+
# The tempfile.path should be free to use now
|
98
111
|
tempfile = Tempfile.new
|
99
112
|
to ||= tempfile.path
|
100
113
|
tempfile.unlink
|
114
|
+
|
101
115
|
if !overwrite && File.exist?(to)
|
102
116
|
raise Client::RuntimeError, "File [#{to}] already exist locally"
|
103
117
|
end
|
@@ -108,6 +122,11 @@ module SMB
|
|
108
122
|
false
|
109
123
|
end
|
110
124
|
|
125
|
+
# Reads a remote file and return its content
|
126
|
+
# @param [String] from The file to be read from server
|
127
|
+
# @param [Boolean] overwrite Overwrite if exist locally?
|
128
|
+
# @param [Boolean] raise raise Error or just return +false+
|
129
|
+
# @return [String] The content of the remote file
|
111
130
|
def read(from, overwrite = false, raise = true)
|
112
131
|
tempfile = Tempfile.new
|
113
132
|
to = tempfile.path
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'time'
|
2
|
+
|
3
|
+
module SMB
|
4
|
+
module ClientHelper
|
5
|
+
class LsItem
|
6
|
+
REGEX = /(?<name>[\.|\w]+)\s+(?<type>.)\s+(?<size>\d+)\s+(?<change_time>.+)/
|
7
|
+
|
8
|
+
attr_accessor :name, :type, :size, :change_time
|
9
|
+
|
10
|
+
def file?
|
11
|
+
@type.include? 'N'
|
12
|
+
end
|
13
|
+
|
14
|
+
def directory?
|
15
|
+
@type.include? 'D'
|
16
|
+
end
|
17
|
+
|
18
|
+
def hidden?
|
19
|
+
@type.include? 'H'
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.from_line(line)
|
23
|
+
match_data = REGEX.match line
|
24
|
+
return nil unless match_data
|
25
|
+
|
26
|
+
item = LsItem.new
|
27
|
+
item.name = match_data['name']
|
28
|
+
item.type = match_data['type']
|
29
|
+
item.size = match_data['size'].to_i
|
30
|
+
item.change_time = Time.parse match_data['change_time']
|
31
|
+
item
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/smb/client/version.rb
CHANGED
data/smb-client.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: smb-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ralf Herzog
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-20 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: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: simplecov
|
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: SMB Client wrapper for smbclient executable
|
56
70
|
email:
|
57
71
|
- ralf@rherzog.de
|
@@ -73,6 +87,7 @@ files:
|
|
73
87
|
- lib/smb/client/client.rb
|
74
88
|
- lib/smb/client/client_helper.rb
|
75
89
|
- lib/smb/client/connection_error.rb
|
90
|
+
- lib/smb/client/ls_item.rb
|
76
91
|
- lib/smb/client/runtime_error.rb
|
77
92
|
- lib/smb/client/version.rb
|
78
93
|
- smb-client.gemspec
|