sambal 0.1.6 → 0.1.7

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: abe20faeafb0cf4e5117a5decfec59c43c440501
4
- data.tar.gz: 20032ebe666efcf9ed27274e28a014917dca1000
3
+ metadata.gz: 38f975857d880b0980139c775c4209198a0fc61d
4
+ data.tar.gz: 736a0bff136bf70413f17df9e54a691b38e26a3a
5
5
  SHA512:
6
- metadata.gz: cbf2111bb855e33b98a28ac6b6c7a0e8c193a03ddfa89b4cc6ea028f5709a010caf66b27789b904a10143b32fed61a28033f0f039bdc40a34330650e9767a14b
7
- data.tar.gz: 62c67112d634d2a832a8a97674a9b2c22aec9c1abd24c3e0300d24082e9731af619ceced796c345f2d5a94c8922b049e5669baf7cae35f55d280f9b41d2ad93e
6
+ metadata.gz: c64dd602dc5e03c8c5d4b2f72664e0fd2edf37fca88b795ee0f1ebb9d977d483c0e071728d187f45ce10bbbf4cb94f20b4fc7fe62a2eea031d11909201b07fad
7
+ data.tar.gz: 16d10c22578db5eb2ac0b30835d892b41588cf4a79b953d9ad3231e0c3735a8808001edde69f8d1631470d9ff41a997fe5aacc9017efd66f34c2fb9c8cb20be6
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in sambal.gemspec
4
4
  gemspec
5
+
6
+ gem 'rspec_junit_formatter', '0.2.2'
data/README.md CHANGED
@@ -1,3 +1,5 @@
1
+ [![Circle CI](https://circleci.com/gh/johnae/sambal.svg?style=svg)](https://circleci.com/gh/johnae/sambal)
2
+
1
3
  # Sambal
2
4
 
3
5
  Sambal is a ruby samba client
data/Spookfile ADDED
@@ -0,0 +1,11 @@
1
+ -- How much output do we want?
2
+ log_level "INFO"
3
+
4
+ rspec = command "bundle exec rspec -f d"
5
+
6
+ watch "lib", "spec", ->
7
+ on_changed "^(spec)/(spec_helper%.rb)", -> rspec "spec"
8
+ on_changed "^spec/(.*)_spec%.rb", (a) -> rspec "spec/#{a}_spec.rb"
9
+ on_changed "^lib/sambal%.rb", (a) -> rspec "spec/sambal/client_spec.rb"
10
+
11
+ notifier "#{os.getenv('HOME')}/.spook/notifiers"
data/circle.yml ADDED
@@ -0,0 +1,4 @@
1
+ dependencies:
2
+ pre:
3
+ - sudo apt-get update -qq
4
+ - sudo apt-get install -y smbclient samba
data/lib/sambal.rb CHANGED
@@ -1,284 +1,10 @@
1
- # coding: UTF-8
2
-
3
- require "sambal/version"
4
- require 'open3'
5
- require 'logger'
6
- require 'json'
7
- require 'pty'
8
- require 'expect'
9
1
  require 'time'
10
2
  require 'tempfile'
11
3
 
12
- module Sambal
4
+ require 'sambal/version'
5
+ require 'sambal/client'
6
+ require 'sambal/response'
13
7
 
8
+ module Sambal
14
9
  class InternalError < RuntimeError; end
15
-
16
- class Response
17
-
18
- attr_reader :message
19
-
20
- def initialize(message, success)
21
- msg = message.split("\n")
22
- msg.each do |line|
23
- if line =~ /^NT\_.*\s/
24
- @message = line
25
- end
26
- end
27
- @message ||= message
28
- @success = success
29
- end
30
-
31
- def success?
32
- @success
33
- end
34
-
35
- def failure?
36
- !success?
37
- end
38
-
39
- end
40
-
41
- class Client
42
-
43
- attr_reader :connected
44
-
45
- def initialize(options={})
46
- begin
47
- options = {domain: 'WORKGROUP', host: '127.0.0.1', share: '', user: 'guest', password: '--no-pass', port: 445, timeout: 10}.merge(options)
48
- @timeout = options[:timeout].to_i
49
- @o, @i, @pid = PTY.spawn("smbclient \"//#{options[:host]}/#{options[:share]}\" '#{options[:password]}' -W \"#{options[:domain]}\" -U \"#{options[:user]}\" -p #{options[:port]}")
50
- #@o.set_encoding('UTF-8:UTF-8') ## don't know didn't work, we only have this problem when the files are named using non-english characters
51
- #@i.set_encoding('UTF-8:UTF-8')
52
- res = @o.expect(/(.*\n)?smb:.*\\>/, @timeout)[0] rescue nil
53
- @connected = case res
54
- when nil
55
- $stderr.puts "Failed to connect"
56
- false
57
- when /^put/
58
- res['putting'].nil? ? false : true
59
- else
60
- if res['NT_STATUS']
61
- false
62
- elsif res['timed out'] || res['Server stopped']
63
- false
64
- else
65
- true
66
- end
67
- end
68
-
69
- unless @connected
70
- close if @pid
71
- exit(1)
72
- end
73
- rescue Exception => e
74
- raise RuntimeError.exception("Unknown Process Failed!! (#{$!.to_s}): #{e.message.inspect}\n"+e.backtrace.join("\n"))
75
- end
76
- end
77
-
78
- def logger
79
- @logger ||= Logger.new(STDOUT)
80
- end
81
-
82
- def logger=(l)
83
- @logger = l
84
- end
85
-
86
- def file_context(path)
87
- if (path_parts = path.split('/')).length>1
88
- file = path_parts.pop
89
- subdirs = path_parts.length
90
- dir = path_parts.join('/')
91
- cd dir
92
- else
93
- file = path
94
- end
95
- begin
96
- yield(file)
97
- ensure
98
- unless subdirs.nil?
99
- subdirs.times { cd '..' }
100
- end
101
- end
102
- end
103
-
104
- def ls(qualifier = '*')
105
- parse_files(ask_wrapped('ls', qualifier))
106
- end
107
-
108
- def cd(dir)
109
- response = ask("cd \"#{dir}\"")
110
- if response.split("\r\n").join('') =~ /NT_STATUS_OBJECT_NAME_NOT_FOUND/
111
- Response.new(response, false)
112
- else
113
- Response.new(response, true)
114
- end
115
- end
116
-
117
- def get(file, output)
118
- begin
119
- file_context(file) do |file|
120
- response = ask_wrapped 'get', [file, output]
121
- if response =~ /^getting\sfile.*$/
122
- Response.new(response, true)
123
- else
124
- Response.new(response, false)
125
- end
126
- end
127
- rescue InternalError => e
128
- Response.new(e.message, false)
129
- end
130
- end
131
-
132
- def put(file, destination)
133
- response = ask_wrapped 'put', [file, destination]
134
- if response =~ /^putting\sfile.*$/
135
- Response.new(response, true)
136
- else
137
- Response.new(response, false)
138
- end
139
- rescue InternalError => e
140
- Response.new(e.message, false)
141
- end
142
-
143
- def put_content(content, destination)
144
- t = Tempfile.new("upload-smb-content-#{destination}")
145
- File.open(t.path, 'w') do |f|
146
- f << content
147
- end
148
- response = ask_wrapped 'put', [t.path, destination]
149
- if response =~ /^putting\sfile.*$/
150
- Response.new(response, true)
151
- else
152
- Response.new(response, false)
153
- end
154
- rescue InternalError => e
155
- Response.new(e.message, false)
156
- ensure
157
- t.close
158
- end
159
-
160
- def rmdir(dir)
161
- response = cd dir
162
- return response if response.failure?
163
- begin
164
- ls.each do |name, meta|
165
- if meta[:type]==:file
166
- response = del name
167
- elsif meta[:type]==:directory && !(name =~ /^\.+$/)
168
- response = rmdir(name)
169
- end
170
- raise InternalError.new response.message if response && response.failure?
171
- end
172
- cd '..'
173
- response = ask_wrapped 'rmdir', dir
174
- next_line = response.split("\n")[1]
175
- if next_line =~ /^smb:.*\\>/
176
- Response.new(response, true)
177
- else
178
- Response.new(response, false)
179
- end
180
- rescue InternalError => e
181
- Response.new(e.message, false)
182
- end
183
- end
184
-
185
- def del(file)
186
- begin
187
- file_context(file) do |file|
188
- response = ask_wrapped 'del', file
189
- next_line = response.split("\n")[1]
190
- if next_line =~ /^smb:.*\\>/
191
- Response.new(response, true)
192
- #elsif next_line =~ /^NT_STATUS_NO_SUCH_FILE.*$/
193
- # Response.new(response, false)
194
- #elsif next_line =~ /^NT_STATUS_ACCESS_DENIED.*$/
195
- # Response.new(response, false)
196
- else
197
- Response.new(response, false)
198
- end
199
- end
200
- rescue InternalError => e
201
- Response.new(e.message, false)
202
- end
203
- #end
204
- #if (path_parts = file.split('/')).length>1
205
- # file = path_parts.pop
206
- # subdirs = path_parts.length
207
- # dir = path_parts.join('/')
208
- # cd dir
209
- #end
210
- # response = ask "del #{file}"
211
- # next_line = response.split("\n")[1]
212
- # if next_line =~ /^smb:.*\\>/
213
- # Response.new(response, true)
214
- # #elsif next_line =~ /^NT_STATUS_NO_SUCH_FILE.*$/
215
- # # Response.new(response, false)
216
- # #elsif next_line =~ /^NT_STATUS_ACCESS_DENIED.*$/
217
- # # Response.new(response, false)
218
- # else
219
- # Response.new(response, false)
220
- # end
221
- #rescue InternalError => e
222
- # Response.new(e.message, false)
223
- #ensure
224
- # unless subdirs.nil?
225
- # subdirs.times { cd '..' }
226
- # end
227
- end
228
-
229
- def close
230
- @i.close
231
- @o.close
232
- Process.wait(@pid)
233
- @connected = false
234
- end
235
-
236
- def ask(cmd)
237
- @i.printf("#{cmd}\n")
238
- response = @o.expect(/^smb:.*\\>/,@timeout)[0] rescue nil
239
- if response.nil?
240
- $stderr.puts "Failed to do #{cmd}"
241
- raise Exception.new, "Failed to do #{cmd}"
242
- else
243
- response
244
- end
245
- end
246
-
247
- def ask_wrapped(cmd,filenames)
248
- ask wrap_filenames(cmd,filenames)
249
- end
250
-
251
- def wrap_filenames(cmd,filenames)
252
- filenames = [filenames] unless filenames.kind_of?(Array)
253
- filenames.map!{ |filename| "\"#{filename}\"" }
254
- [cmd,filenames].flatten.join(' ')
255
- end
256
-
257
- def parse_files(str)
258
- files = {}
259
- str.each_line do |line|
260
- if line =~ /\s+([\w\.\d\-\_\?\!\s]+)\s+([DAH]?)\s+(\d+)\s+(.+)$/
261
- lsplit = line.split(/\s{2,}/)
262
- #$stderr.puts "lsplit: #{lsplit}"
263
- lsplit.shift ## remove first empty string
264
- name = lsplit.shift#$1
265
- if lsplit.first =~ /^[A-Za-z]+$/
266
- type = lsplit.shift
267
- else
268
- type = ""
269
- end
270
- size = lsplit.shift#$3
271
- date = lsplit.join(' ')#$4
272
- name.gsub!(/\s+$/,'')
273
- files[name] = if type =~/^D.*$/
274
- {type: :directory, size: size, modified: (Time.parse(date) rescue "!!#{date}")}
275
- else
276
- {type: :file, size: size , modified: (Time.parse(date) rescue "!!#{date}")}
277
- end
278
- end
279
- end
280
- files
281
- end
282
-
283
- end
284
10
  end
@@ -0,0 +1,258 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'logger'
4
+ require 'pty'
5
+ require 'expect'
6
+
7
+ module Sambal
8
+ class Client
9
+
10
+ attr_reader :connected
11
+
12
+ def initialize(options={})
13
+ begin
14
+ options = {domain: 'WORKGROUP', host: '127.0.0.1', share: '', user: 'guest', password: '--no-pass', port: 445, timeout: 10, columns: 80}.merge(options)
15
+ @timeout = options[:timeout].to_i
16
+ @o, @i, @pid = PTY.spawn("COLUMNS=#{options[:columns]} smbclient \"//#{options[:host]}/#{options[:share]}\" '#{options[:password]}' -W \"#{options[:domain]}\" -U \"#{options[:user]}\" -p #{options[:port]}")
17
+ res = @o.expect(/(.*\n)?smb:.*\\>/, @timeout)[0] rescue nil
18
+ @connected = case res
19
+ when nil
20
+ $stderr.puts "Failed to connect"
21
+ false
22
+ when /^put/
23
+ res['putting'].nil? ? false : true
24
+ else
25
+ if res['NT_STATUS']
26
+ false
27
+ elsif res['timed out'] || res['Server stopped']
28
+ false
29
+ else
30
+ true
31
+ end
32
+ end
33
+
34
+ unless @connected
35
+ close if @pid
36
+ exit(1)
37
+ end
38
+ rescue Exception => e
39
+ raise RuntimeError.exception("Unknown Process Failed!! (#{$!.to_s}): #{e.message.inspect}\n"+e.backtrace.join("\n"))
40
+ end
41
+ end
42
+
43
+ def logger
44
+ @logger ||= Logger.new(STDOUT)
45
+ end
46
+
47
+ def logger=(l)
48
+ @logger = l
49
+ end
50
+
51
+ def file_context(path)
52
+ if (path_parts = path.split('/')).length>1
53
+ file = path_parts.pop
54
+ subdirs = path_parts.length
55
+ dir = path_parts.join('/')
56
+ cd dir
57
+ else
58
+ file = path
59
+ end
60
+ begin
61
+ yield(file)
62
+ ensure
63
+ unless subdirs.nil?
64
+ subdirs.times { cd '..' }
65
+ end
66
+ end
67
+ end
68
+
69
+ def ls(qualifier = '*')
70
+ parse_files(ask_wrapped('ls', qualifier))
71
+ end
72
+
73
+ def cd(dir)
74
+ response = ask("cd \"#{dir}\"")
75
+ if response.split("\r\n").join('') =~ /NT_STATUS_OBJECT_NAME_NOT_FOUND/
76
+ Response.new(response, false)
77
+ else
78
+ Response.new(response, true)
79
+ end
80
+ end
81
+
82
+ def get(file, output)
83
+ begin
84
+ file_context(file) do |file|
85
+ response = ask_wrapped 'get', [file, output]
86
+ if response =~ /^getting\sfile.*$/
87
+ Response.new(response, true)
88
+ else
89
+ Response.new(response, false)
90
+ end
91
+ end
92
+ rescue InternalError => e
93
+ Response.new(e.message, false)
94
+ end
95
+ end
96
+
97
+ def put(file, destination)
98
+ response = ask_wrapped 'put', [file, destination]
99
+ if response =~ /^putting\sfile.*$/
100
+ Response.new(response, true)
101
+ else
102
+ Response.new(response, false)
103
+ end
104
+ rescue InternalError => e
105
+ Response.new(e.message, false)
106
+ end
107
+
108
+ def put_content(content, destination)
109
+ t = Tempfile.new("upload-smb-content-#{destination}")
110
+ File.open(t.path, 'w') do |f|
111
+ f << content
112
+ end
113
+ response = ask_wrapped 'put', [t.path, destination]
114
+ if response =~ /^putting\sfile.*$/
115
+ Response.new(response, true)
116
+ else
117
+ Response.new(response, false)
118
+ end
119
+ rescue InternalError => e
120
+ Response.new(e.message, false)
121
+ ensure
122
+ t.close
123
+ end
124
+
125
+ def mkdir(directory)
126
+ return Response.new('directory name is empty', false) if directory.strip.empty?
127
+ response = ask_wrapped('mkdir', directory)
128
+ if response =~ /NT_STATUS_OBJECT_NAME_(INVALID|COLLISION)/
129
+ Response.new(response, false)
130
+ else
131
+ Response.new(response, true)
132
+ end
133
+ end
134
+
135
+ def rmdir(dir)
136
+ response = cd dir
137
+ return response if response.failure?
138
+ begin
139
+ ls.each do |name, meta|
140
+ if meta[:type]==:file
141
+ response = del name
142
+ elsif meta[:type]==:directory && !(name =~ /^\.+$/)
143
+ response = rmdir(name)
144
+ end
145
+ raise InternalError.new response.message if response && response.failure?
146
+ end
147
+ cd '..'
148
+ response = ask_wrapped 'rmdir', dir
149
+ next_line = response.split("\n")[1]
150
+ if next_line =~ /^smb:.*\\>/
151
+ Response.new(response, true)
152
+ else
153
+ Response.new(response, false)
154
+ end
155
+ rescue InternalError => e
156
+ Response.new(e.message, false)
157
+ end
158
+ end
159
+
160
+ def del(file)
161
+ begin
162
+ file_context(file) do |file|
163
+ response = ask_wrapped 'del', file
164
+ next_line = response.split("\n")[1]
165
+ if next_line =~ /^smb:.*\\>/
166
+ Response.new(response, true)
167
+ #elsif next_line =~ /^NT_STATUS_NO_SUCH_FILE.*$/
168
+ # Response.new(response, false)
169
+ #elsif next_line =~ /^NT_STATUS_ACCESS_DENIED.*$/
170
+ # Response.new(response, false)
171
+ else
172
+ Response.new(response, false)
173
+ end
174
+ end
175
+ rescue InternalError => e
176
+ Response.new(e.message, false)
177
+ end
178
+ #end
179
+ #if (path_parts = file.split('/')).length>1
180
+ # file = path_parts.pop
181
+ # subdirs = path_parts.length
182
+ # dir = path_parts.join('/')
183
+ # cd dir
184
+ #end
185
+ # response = ask "del #{file}"
186
+ # next_line = response.split("\n")[1]
187
+ # if next_line =~ /^smb:.*\\>/
188
+ # Response.new(response, true)
189
+ # #elsif next_line =~ /^NT_STATUS_NO_SUCH_FILE.*$/
190
+ # # Response.new(response, false)
191
+ # #elsif next_line =~ /^NT_STATUS_ACCESS_DENIED.*$/
192
+ # # Response.new(response, false)
193
+ # else
194
+ # Response.new(response, false)
195
+ # end
196
+ #rescue InternalError => e
197
+ # Response.new(e.message, false)
198
+ #ensure
199
+ # unless subdirs.nil?
200
+ # subdirs.times { cd '..' }
201
+ # end
202
+ end
203
+
204
+ def close
205
+ @i.close
206
+ @o.close
207
+ Process.wait(@pid)
208
+ @connected = false
209
+ end
210
+
211
+ def ask(cmd)
212
+ @i.printf("#{cmd}\n")
213
+ response = @o.expect(/^smb:.*\\>/,@timeout)[0] rescue nil
214
+ if response.nil?
215
+ $stderr.puts "Failed to do #{cmd}"
216
+ raise Exception.new, "Failed to do #{cmd}"
217
+ else
218
+ response
219
+ end
220
+ end
221
+
222
+ def ask_wrapped(cmd,filenames)
223
+ ask wrap_filenames(cmd,filenames)
224
+ end
225
+
226
+ def wrap_filenames(cmd,filenames)
227
+ filenames = [filenames] unless filenames.kind_of?(Array)
228
+ filenames.map!{ |filename| "\"#{filename}\"" }
229
+ [cmd,filenames].flatten.join(' ')
230
+ end
231
+
232
+ def parse_files(str)
233
+ files = {}
234
+ str.each_line do |line|
235
+ if line =~ /\s+([\w\.\d\-\_\?\!\s]+)\s+([DAH]?)\s+(\d+)\s+(.+)$/
236
+ lsplit = line.split(/\s{2,}/)
237
+ #$stderr.puts "lsplit: #{lsplit}"
238
+ lsplit.shift ## remove first empty string
239
+ name = lsplit.shift#$1
240
+ if lsplit.first =~ /^[A-Za-z]+$/
241
+ type = lsplit.shift
242
+ else
243
+ type = ""
244
+ end
245
+ size = lsplit.shift#$3
246
+ date = lsplit.join(' ')#$4
247
+ name.gsub!(/\s+$/,'')
248
+ files[name] = if type =~/^D.*$/
249
+ {type: :directory, size: size, modified: (Time.parse(date) rescue "!!#{date}")}
250
+ else
251
+ {type: :file, size: size , modified: (Time.parse(date) rescue "!!#{date}")}
252
+ end
253
+ end
254
+ end
255
+ files
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,25 @@
1
+ module Sambal
2
+ class Response
3
+
4
+ attr_reader :message
5
+
6
+ def initialize(message, success)
7
+ msg = message.split("\n")
8
+ msg.each do |line|
9
+ if line =~ /^NT\_.*\s/
10
+ @message = line
11
+ end
12
+ end
13
+ @message ||= message
14
+ @success = success
15
+ end
16
+
17
+ def success?
18
+ @success
19
+ end
20
+
21
+ def failure?
22
+ !success?
23
+ end
24
+ end
25
+ end
@@ -34,6 +34,8 @@
34
34
 
35
35
  ## Browsing/Identification ###
36
36
 
37
+ ncalrpc dir = <%= ncalrpc_dir %>
38
+
37
39
  # Change this to the workgroup/NT-domain name your Samba server will part of
38
40
  workgroup = WORKGROUP
39
41
 
@@ -75,7 +77,7 @@
75
77
 
76
78
  # This tells Samba to use a separate log file for each machine
77
79
  # that connects
78
- log file = /tmp/vp6samba/samba/log.%m
80
+ log file = <%= log_path %>/log.%m
79
81
 
80
82
  # Cap the size of the individual log files (in KiB).
81
83
  max log size = 1000
@@ -99,8 +101,8 @@
99
101
  # in this server for every user accessing the server. See
100
102
  # /usr/share/doc/samba-doc/htmldocs/Samba3-HOWTO/ServerType.html
101
103
  # in the samba-doc package for details.
102
- # security = user
103
- security = share
104
+ security = user
105
+ # security = share
104
106
  # we set it to whoever is running the specs
105
107
  guest account = <%= local_user %>
106
108
 
@@ -26,20 +26,30 @@ module Sambal
26
26
  attr_reader :port
27
27
  attr_reader :share_path
28
28
  attr_reader :root_path
29
+ attr_reader :tmp_path
30
+ attr_reader :private_dir
31
+ attr_reader :cache_dir
32
+ attr_reader :state_dir
29
33
  attr_reader :config_path
30
34
  attr_reader :share_name
31
35
  attr_reader :run_as
32
36
  attr_reader :host
33
37
 
34
- def initialize(root_path="/tmp/sambal_test_server_#{Time.now.to_i}", share_name='sambal_test', run_as=ENV['USER'])
38
+ def initialize(share_name='sambal_test', run_as=ENV['USER'])
35
39
  @erb_path = "#{File.expand_path(File.dirname(__FILE__))}/smb.conf.erb"
36
40
  @host = "127.0.0.1" ## will always just be localhost
37
- @root_path = root_path
38
- @share_path = "#{root_path}/share"
41
+ @root_path = File.expand_path(File.dirname(File.dirname(File.dirname(__FILE__))))
42
+ @tmp_path = "#{root_path}/spec_tmp"
43
+ @share_path = "#{tmp_path}/share"
39
44
  @share_name = share_name
40
- @config_path = "#{root_path}/smb.conf"
41
- @lock_path = "#{root_path}"
42
- @pid_dir = "#{root_path}"
45
+ @config_path = "#{tmp_path}/smb.conf"
46
+ @lock_path = "#{tmp_path}"
47
+ @pid_dir = "#{tmp_path}"
48
+ @cache_dir = "#{tmp_path}"
49
+ @state_dir = "#{tmp_path}"
50
+ @log_path = "#{tmp_path}"
51
+ @private_dir = "#{tmp_path}"
52
+ @ncalrpc_dir = "#{tmp_path}"
43
53
  @port = Random.new(Time.now.to_i).rand(2345..5678).to_i
44
54
  @run_as = run_as
45
55
  FileUtils.mkdir_p @share_path
@@ -53,18 +63,18 @@ module Sambal
53
63
 
54
64
  def write_config
55
65
  File.open(@config_path, 'w') do |f|
56
- f << Document.new(IO.binread(@erb_path)).interpolate(samba_share: @share_path, local_user: @run_as, share_name: @share_name)
66
+ f << Document.new(IO.binread(@erb_path)).interpolate(samba_share: @share_path, local_user: @run_as, share_name: @share_name, log_path: @log_path, ncalrpc_dir: @ncalrpc_dir)
57
67
  end
58
68
  end
59
69
 
60
70
  def start
61
71
  if RUBY_PLATFORM=="java"
62
72
  @smb_server_pid = Thread.new do
63
- `smbd -S -F -s #{@config_path} -p #{@port} --lockdir=#{@lock_path} --piddir=#{@pid_dir}`
73
+ `smbd -S -F -s #{@config_path} -p #{@port} --lockdir=#{@lock_path} --piddir=#{@pid_dir} --private-dir=#{@private_dir} --cachedir=#{@cache_dir} --statedir=#{@state_dir} > #{@log_path}/smb.log`
64
74
  end
65
75
  else
66
76
  @smb_server_pid = fork do
67
- `smbd -S -F -s #{@config_path} -p #{@port} --lockdir=#{@lock_path} --piddir=#{@pid_dir}`
77
+ `smbd -S -F -s #{@config_path} -p #{@port} --lockdir=#{@lock_path} --piddir=#{@pid_dir} --private-dir=#{@private_dir} --cachedir=#{@cache_dir} --statedir=#{@state_dir} > #{@log_path}/smb.log`
68
78
  end
69
79
  end
70
80
  sleep 2 ## takes a short time to start up
@@ -78,8 +88,8 @@ module Sambal
78
88
 
79
89
  def stop!
80
90
  stop
81
- FileUtils.rm_rf @root_path
91
+ FileUtils.rm_rf @tmp_path unless ENV.key?('KEEP_SMB_TMP')
82
92
  end
83
93
 
84
94
  end
85
- end
95
+ end
@@ -1,5 +1,5 @@
1
1
  # coding: UTF-8
2
2
 
3
3
  module Sambal
4
- VERSION = "0.1.6"
4
+ VERSION = "0.1.7"
5
5
  end
data/sambal.gemspec CHANGED
@@ -15,5 +15,5 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Sambal::VERSION
17
17
 
18
- gem.add_development_dependency "rspec", '>=2.6.0'
18
+ gem.add_development_dependency "rspec", '>=3.4.0'
19
19
  end
@@ -5,31 +5,47 @@ require 'tempfile'
5
5
 
6
6
  describe Sambal::Client do
7
7
 
8
+ TEST_DIRECTORY_WITH_SPACE_IN_NAME = 'my dir with spaces in name'
9
+ TEST_FILE_IN_DIRECTORY_WITH_SPACE_IN_NAME = 'a_file_in_a_dir_with_spaces_in_name'
10
+ TEST_SPACES_IN_NAME_PATH = "#{TEST_DIRECTORY_WITH_SPACE_IN_NAME}/#{TEST_FILE_IN_DIRECTORY_WITH_SPACE_IN_NAME}"
11
+ TEST_DIRECTORY = 'testdir'
12
+ TEST_SUB_DIRECTORY = 'testdir_sub'
13
+ SUB_DIRECTORY_PATH = "#{TEST_DIRECTORY}/#{TEST_SUB_DIRECTORY}"
14
+ TESTFILE = 'testfile.txt'
15
+ TESTFILE2 = 'testfile.tx'
16
+ TESTFILE3 = 'testfil.txt'
17
+ TESTFILE_SUB = 'testfile_sub.txt'
18
+ TESTFILE_SUB_PATH = "#{SUB_DIRECTORY_PATH}/#{TESTFILE_SUB}"
19
+
8
20
  before(:all) do
9
21
  @sambal_client = described_class.new(host: test_server.host, share: test_server.share_name, port: test_server.port)
10
22
  end
11
23
 
12
24
  before(:each) do
13
- File.open("#{test_server.share_path}/#{testfile}", 'w') do |f|
25
+ File.open("#{test_server.share_path}/#{TESTFILE}", 'w') do |f|
14
26
  f << "Hello"
15
27
  end
16
- FileUtils.mkdir_p "#{test_server.share_path}/#{test_directory_with_space_in_name}"
17
- File.open("#{test_server.share_path}/#{test_directory_with_space_in_name}/#{test_file_in_directory_with_space_in_name}", 'w') do |f|
28
+ FileUtils.mkdir_p "#{test_server.share_path}/#{TEST_DIRECTORY_WITH_SPACE_IN_NAME}"
29
+ File.open("#{test_server.share_path}/#{TEST_DIRECTORY_WITH_SPACE_IN_NAME}/#{TEST_FILE_IN_DIRECTORY_WITH_SPACE_IN_NAME}", 'w') do |f|
18
30
  f << "Hello there"
19
31
  end
20
- FileUtils.mkdir_p "#{test_server.share_path}/#{test_directory}"
21
- FileUtils.mkdir_p "#{test_server.share_path}/#{test_directory}/#{test_sub_directory}"
22
- File.open("#{test_server.share_path}/#{test_directory}/#{test_sub_directory}/#{testfile_sub}", 'w') do |f|
32
+ FileUtils.mkdir_p "#{test_server.share_path}/#{TEST_DIRECTORY}"
33
+ FileUtils.mkdir_p "#{test_server.share_path}/#{TEST_DIRECTORY}/#{TEST_SUB_DIRECTORY}"
34
+ File.open("#{test_server.share_path}/#{TEST_DIRECTORY}/#{TEST_SUB_DIRECTORY}/#{TESTFILE_SUB}", 'w') do |f|
23
35
  f << "Hello"
24
36
  end
25
- FileUtils.chmod 0775, "#{test_server.share_path}/#{test_directory_with_space_in_name}/#{test_file_in_directory_with_space_in_name}"
26
- FileUtils.chmod 0775, "#{test_server.share_path}/#{test_directory}/#{test_sub_directory}/#{testfile_sub}"
27
- FileUtils.chmod 0775, "#{test_server.share_path}/#{test_directory}/#{test_sub_directory}"
28
- FileUtils.chmod 0775, "#{test_server.share_path}/#{test_directory}"
29
- FileUtils.chmod 0777, "#{test_server.share_path}/#{testfile}"
37
+ FileUtils.chmod 0775, "#{test_server.share_path}/#{TEST_DIRECTORY_WITH_SPACE_IN_NAME}/#{TEST_FILE_IN_DIRECTORY_WITH_SPACE_IN_NAME}"
38
+ FileUtils.chmod 0775, "#{test_server.share_path}/#{TEST_DIRECTORY}/#{TEST_SUB_DIRECTORY}/#{TESTFILE_SUB}"
39
+ FileUtils.chmod 0775, "#{test_server.share_path}/#{TEST_DIRECTORY}/#{TEST_SUB_DIRECTORY}"
40
+ FileUtils.chmod 0775, "#{test_server.share_path}/#{TEST_DIRECTORY}"
41
+ FileUtils.chmod 0777, "#{test_server.share_path}/#{TESTFILE}"
30
42
  @sambal_client.cd('/')
31
43
  end
32
44
 
45
+ after(:each) do
46
+ FileUtils.rm_rf "#{test_server.share_path}/*"
47
+ end
48
+
33
49
  after(:all) do
34
50
  @sambal_client.close
35
51
  end
@@ -42,174 +58,175 @@ describe Sambal::Client do
42
58
  t
43
59
  end
44
60
 
45
- let(:test_directory_with_space_in_name) { 'my dir with spaces in name' }
46
-
47
- let(:test_file_in_directory_with_space_in_name) { 'a_file_in_a_dir_with_spaces_in_name' }
48
-
49
- let(:test_spaces_in_name_path) { "#{test_directory_with_space_in_name}/#{test_file_in_directory_with_space_in_name}" }
50
-
51
- let(:test_directory) do
52
- 'testdir'
53
- end
54
-
55
- let(:test_sub_directory) do
56
- 'testdir_sub'
57
- end
58
-
59
- let(:sub_directory_path) do
60
- "#{test_directory}/#{test_sub_directory}"
61
- end
62
-
63
- let(:testfile) do
64
- 'testfile.txt'
65
- end
66
-
67
- let(:testfile2) do
68
- 'testfile.tx'
69
- end
70
-
71
- let(:testfile3) do
72
- 'testfil.txt'
73
- end
74
-
75
- let(:testfile_sub) do
76
- 'testfile_sub.txt'
77
- end
78
-
79
- let(:testfile_sub_path) do
80
- "#{sub_directory_path}/#{testfile_sub}"
81
- end
82
-
83
61
  describe 'ls' do
84
62
  before(:all) do
85
- FileUtils.cp "#{test_server.share_path}/#{testfile}", "#{test_server.share_path}/#{testfile2}"
86
- FileUtils.cp "#{test_server.share_path}/#{testfile}", "#{test_server.share_path}/#{testfile3}"
63
+ FileUtils.cp "#{test_server.share_path}/#{TESTFILE}", "#{test_server.share_path}/#{TESTFILE2}"
64
+ FileUtils.cp "#{test_server.share_path}/#{TESTFILE}", "#{test_server.share_path}/#{TESTFILE3}"
87
65
  end
88
66
 
89
67
  it "should list files with spaces in their names" do
90
68
  result = @sambal_client.ls
91
- result.should have_key(test_directory_with_space_in_name)
69
+ expect(result).to have_key(TEST_DIRECTORY_WITH_SPACE_IN_NAME)
92
70
  end
93
71
 
94
72
  it "should list files on an smb server" do
95
73
  result = @sambal_client.ls
96
- result.should have_key(testfile)
97
- result.should have_key(testfile2)
98
- result.should have_key(testfile3)
74
+ expect(result).to have_key(TESTFILE)
75
+ expect(result).to have_key(TESTFILE2)
76
+ expect(result).to have_key(TESTFILE3)
99
77
  end
100
78
 
101
79
  it "should list files using a wildcard on an smb server" do
102
80
  result = @sambal_client.ls '*.txt'
103
- result.should have_key(testfile)
104
- result.should_not have_key(testfile2)
105
- result.should have_key(testfile3)
81
+ expect(result).to have_key(TESTFILE)
82
+ expect(result).to_not have_key(TESTFILE2)
83
+ expect(result).to have_key(TESTFILE3)
84
+ end
85
+ end
86
+
87
+ describe 'mkdir' do
88
+ before(:all) do
89
+ @sambal_client.cd('/')
90
+ end
91
+
92
+ it 'should create a new directory' do
93
+ result = @sambal_client.mkdir('test')
94
+ expect(result).to be_successful
95
+
96
+ expect(@sambal_client.ls).to have_key('test')
97
+ end
98
+
99
+ it 'should create a directory with spaces' do
100
+ result = @sambal_client.mkdir('test spaces directory')
101
+ expect(result).to be_successful
102
+ expect(@sambal_client.ls).to have_key('test spaces directory')
103
+ end
104
+
105
+ it 'should not create an invalid directory' do
106
+ result = @sambal_client.mkdir('**')
107
+ expect(result).to_not be_successful
108
+ end
109
+
110
+ it 'should not overwrite an existing directory' do
111
+ # Ensure our test directory exists
112
+ @sambal_client.rmdir('test')
113
+ @sambal_client.mkdir('test')
114
+ expect(@sambal_client.ls).to have_key('test')
115
+
116
+ result = @sambal_client.mkdir('test')
117
+ expect(result).to_not be_successful
118
+ end
119
+
120
+ it 'should handle empty directory names' do
121
+ expect(@sambal_client.mkdir('')).to_not be_successful
122
+ expect(@sambal_client.mkdir(' ')).to_not be_successful
106
123
  end
107
124
  end
108
125
 
109
126
  it "should get files from an smb server" do
110
- @sambal_client.get(testfile, "/tmp/sambal_spec_testfile.txt").should be_successful
111
- File.exists?("/tmp/sambal_spec_testfile.txt").should == true
112
- File.size("/tmp/sambal_spec_testfile.txt").should == @sambal_client.ls[testfile][:size].to_i
127
+ expect(@sambal_client.get(TESTFILE, "/tmp/sambal_spec_testfile.txt")).to be_successful
128
+ expect(File.exists?("/tmp/sambal_spec_testfile.txt")).to eq true
129
+ expect(File.size("/tmp/sambal_spec_testfile.txt")).to eq @sambal_client.ls[TESTFILE][:size].to_i
113
130
  end
114
131
 
115
132
  it "should get files in a dir with spaces in it's name from an smb server" do
116
- @sambal_client.get(test_spaces_in_name_path, "/tmp/sambal_this_file_was_in_dir_with_spaces.txt").should be_successful
117
- File.exists?("/tmp/sambal_this_file_was_in_dir_with_spaces.txt").should == true
118
- @sambal_client.cd(test_directory_with_space_in_name)
119
- File.size("/tmp/sambal_this_file_was_in_dir_with_spaces.txt").should == @sambal_client.ls[test_file_in_directory_with_space_in_name][:size].to_i
133
+ expect(@sambal_client.get(TEST_SPACES_IN_NAME_PATH, "/tmp/sambal_this_file_was_in_dir_with_spaces.txt")).to be_successful
134
+ expect(File.exists?("/tmp/sambal_this_file_was_in_dir_with_spaces.txt")).to eq true
135
+ @sambal_client.cd(TEST_DIRECTORY_WITH_SPACE_IN_NAME)
136
+ expect(File.size("/tmp/sambal_this_file_was_in_dir_with_spaces.txt")).to eq @sambal_client.ls[TEST_FILE_IN_DIRECTORY_WITH_SPACE_IN_NAME][:size].to_i
120
137
  end
121
138
 
122
139
  it "should get files in a subdirectory while in a higher level directory from an smb server" do
123
- @sambal_client.get(testfile_sub_path, "/tmp/sambal_spec_testfile_sub.txt").should be_successful
124
- File.exists?("/tmp/sambal_spec_testfile_sub.txt").should == true
125
- @sambal_client.cd(sub_directory_path)
126
- File.size("/tmp/sambal_spec_testfile_sub.txt").should == @sambal_client.ls[testfile_sub][:size].to_i
140
+ expect(@sambal_client.get(TESTFILE_SUB_PATH, "/tmp/sambal_spec_testfile_sub.txt")).to be_successful
141
+ expect(File.exists?("/tmp/sambal_spec_testfile_sub.txt")).to eq true
142
+ @sambal_client.cd(SUB_DIRECTORY_PATH)
143
+ expect(File.size("/tmp/sambal_spec_testfile_sub.txt")).to eq @sambal_client.ls[TESTFILE_SUB][:size].to_i
127
144
  end
128
145
 
129
146
  it "should not be successful when getting a file from an smb server fails" do
130
147
  result = @sambal_client.get("non_existant_file.txt", "/tmp/sambal_spec_non_existant_file.txt")
131
- result.should_not be_successful
132
- result.message.should match /^NT_.*$/
133
- result.message.split("\n").should have(1).line
134
- File.exists?("/tmp/sambal_spec_non_existant_file.txt").should == false
148
+ expect(result).to_not be_successful
149
+ expect(result.message).to match(/^NT_.*$/)
150
+ expect(result.message.split("\n").size).to eq 1
151
+ expect(File.exists?("/tmp/sambal_spec_non_existant_file.txt")).to eq false
135
152
  end
136
153
 
137
154
  it "should upload files to an smb server" do
138
- @sambal_client.ls.should_not have_key("uploaded_file.txt")
139
- @sambal_client.put(file_to_upload.path, 'uploaded_file.txt').should be_successful
140
- @sambal_client.ls.should have_key("uploaded_file.txt")
155
+ expect(@sambal_client.ls).to_not have_key("uploaded_file.txt")
156
+ expect(@sambal_client.put(file_to_upload.path, 'uploaded_file.txt')).to be_successful
157
+ expect(@sambal_client.ls).to have_key("uploaded_file.txt")
141
158
  end
142
159
 
143
160
  it "should upload content to an smb server" do
144
- @sambal_client.ls.should_not have_key("content_uploaded_file.txt")
145
- @sambal_client.put_content("Content upload", 'content_uploaded_file.txt').should be_successful
146
- @sambal_client.ls.should have_key("content_uploaded_file.txt")
161
+ expect(@sambal_client.ls).to_not have_key("content_uploaded_file.txt")
162
+ expect(@sambal_client.put_content("Content upload", 'content_uploaded_file.txt')).to be_successful
163
+ expect(@sambal_client.ls).to have_key("content_uploaded_file.txt")
147
164
  end
148
165
 
149
166
  it "should delete files on an smb server" do
150
- @sambal_client.del(testfile).should be_successful
151
- @sambal_client.ls.should_not have_key(testfile)
167
+ expect(@sambal_client.del(TESTFILE)).to be_successful
168
+ expect(@sambal_client.ls).to_not have_key(TESTFILE)
152
169
  end
153
170
 
154
171
  it "should not be successful when deleting a file from an smb server fails" do
155
172
  result = @sambal_client.del("non_existant_file.txt")
156
- result.should_not be_successful
157
- result.message.should match /^NT_.*$/
158
- result.message.split("\n").should have(1).line
173
+ expect(result).to_not be_successful
174
+ expect(result.message).to match(/^NT_.*$/)
175
+ expect(result.message.split("\n").size).to eq 1
159
176
  end
160
177
 
161
178
  it "should switch directory on an smb server" do
162
- @sambal_client.put_content("testing directories", 'dirtest.txt').should be_successful ## a bit stupid, but now we can check that this isn't listed when we switch dirs
163
- @sambal_client.ls.should have_key('dirtest.txt')
164
- @sambal_client.cd(test_directory).should be_successful
165
- @sambal_client.ls.should_not have_key('dirtest.txt')
166
- @sambal_client.put_content("in #{test_directory}", 'intestdir.txt').should be_successful
167
- @sambal_client.ls.should have_key('intestdir.txt')
168
- @sambal_client.cd('..').should be_successful
169
- @sambal_client.ls.should_not have_key('intestdir.txt')
170
- @sambal_client.ls.should have_key('dirtest.txt')
179
+ expect(@sambal_client.put_content("testing directories", 'dirtest.txt')).to be_successful ## a bit stupid, but now we can check that this isn't listed when we switch dirs
180
+ expect(@sambal_client.ls).to have_key('dirtest.txt')
181
+ expect(@sambal_client.cd(TEST_DIRECTORY)).to be_successful
182
+ expect(@sambal_client.ls).to_not have_key('dirtest.txt')
183
+ expect(@sambal_client.put_content("in #{TEST_DIRECTORY}", 'intestdir.txt')).to be_successful
184
+ expect(@sambal_client.ls).to have_key('intestdir.txt')
185
+ expect(@sambal_client.cd('..')).to be_successful
186
+ expect(@sambal_client.ls).to_not have_key('intestdir.txt')
187
+ expect(@sambal_client.ls).to have_key('dirtest.txt')
171
188
  end
172
189
 
173
190
  it "should delete files in subdirectory while in a higher level directory" do
174
191
  @sambal_client.cd('/')
175
- @sambal_client.cd(test_directory)
176
- @sambal_client.put_content("some content", "file_to_delete").should be_successful
192
+ @sambal_client.cd(TEST_DIRECTORY)
193
+ expect(@sambal_client.put_content("some content", "file_to_delete")).to be_successful
177
194
  @sambal_client.cd('/')
178
- @sambal_client.del("#{test_directory}/file_to_delete").should be_successful
195
+ expect(@sambal_client.del("#{TEST_DIRECTORY}/file_to_delete")).to be_successful
179
196
  @sambal_client.cd('/')
180
- @sambal_client.ls.should have_key("#{testfile}")
197
+ expect(@sambal_client.ls).to have_key("#{TESTFILE}")
181
198
  end
182
199
 
183
200
  it "should recursively delete a directory" do
184
201
  @sambal_client.cd('/')
185
- @sambal_client.cd(test_directory)
186
- @sambal_client.put_content("some content", "file_to_delete").should be_successful
202
+ @sambal_client.cd(TEST_DIRECTORY)
203
+ expect(@sambal_client.put_content("some content", "file_to_delete")).to be_successful
187
204
  @sambal_client.cd('/')
188
- @sambal_client.rmdir("#{test_directory}").should be_successful
205
+ expect(@sambal_client.rmdir("#{TEST_DIRECTORY}")).to be_successful
189
206
  @sambal_client.cd('/')
190
- @sambal_client.ls.should_not have_key("#{test_directory}")
207
+ expect(@sambal_client.ls).to_not have_key("#{TEST_DIRECTORY}")
191
208
  end
192
209
 
193
210
  it "should not be successful when recursively deleting a nonexistant directory" do
194
211
  @sambal_client.cd('/')
195
- @sambal_client.rmdir("this_doesnt_exist").should_not be_successful
212
+ expect(@sambal_client.rmdir("this_doesnt_exist")).to_not be_successful
196
213
  end
197
214
 
198
215
  it "should not be successful when command fails" do
199
216
  result = @sambal_client.put("jhfahsf iasifasifh", "jsfijsf ijidjag")
200
- result.should_not be_successful
217
+ expect(result).to_not be_successful
201
218
  end
202
219
 
203
220
  it 'should create commands with one wrapped filename' do
204
- @sambal_client.wrap_filenames('cmd','file1').should eq('cmd "file1"')
221
+ expect(@sambal_client.wrap_filenames('cmd','file1')).to eq('cmd "file1"')
205
222
  end
206
223
 
207
224
  it 'should create commands with more than one wrapped filename' do
208
- @sambal_client.wrap_filenames('cmd',['file1','file2']).should eq('cmd "file1" "file2"')
225
+ expect(@sambal_client.wrap_filenames('cmd',['file1','file2'])).to eq('cmd "file1" "file2"')
209
226
  end
210
227
 
211
228
  it 'should create commands with pathnames instead of strings' do
212
- @sambal_client.wrap_filenames('cmd',[Pathname.new('file1'), Pathname.new('file2')]).should eq('cmd "file1" "file2"')
229
+ expect(@sambal_client.wrap_filenames('cmd',[Pathname.new('file1'), Pathname.new('file2')])).to eq('cmd "file1" "file2"')
213
230
  end
214
231
 
215
232
  end
data/spec/spec_helper.rb CHANGED
@@ -9,10 +9,11 @@ $:.unshift(lib_path) if File.directory?(lib_path) && !$:.include?(lib_path)
9
9
 
10
10
  require 'sambal'
11
11
  require 'sambal/test_server'
12
+ require 'rspec/expectations'
12
13
 
13
14
  RSpec::Matchers.define :be_successful do
14
15
  match do |actual|
15
- actual.success?.should be_true
16
+ actual.success? == true
16
17
  end
17
18
  end
18
19
 
@@ -31,7 +32,7 @@ RSpec.configure do |config|
31
32
  # config.mock_with :flexmock
32
33
  # config.mock_with :rr
33
34
  config.mock_with :rspec
34
-
35
+
35
36
  ## perhaps this should be removed as well
36
37
  ## and done in Rakefile?
37
38
  config.color = true
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sambal
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Axel Eriksson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-09 00:00:00.000000000 Z
11
+ date: 2016-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 2.6.0
19
+ version: 3.4.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 2.6.0
26
+ version: 3.4.0
27
27
  description: Ruby Samba Client using the cmdline smbclient
28
28
  email:
29
29
  - john@insane.se
@@ -36,7 +36,11 @@ files:
36
36
  - LICENSE
37
37
  - README.md
38
38
  - Rakefile
39
+ - Spookfile
40
+ - circle.yml
39
41
  - lib/sambal.rb
42
+ - lib/sambal/client.rb
43
+ - lib/sambal/response.rb
40
44
  - lib/sambal/smb.conf.erb
41
45
  - lib/sambal/test_server.rb
42
46
  - lib/sambal/version.rb