sambal 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
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