Class: Sambala

Inherits:
Object
  • Object
show all
Includes:
Gardener
Defined in:
lib/sambala.rb,
lib/sambala_gardener.rb

Overview

This class acts as a Ruby wrapper around the smbclient command line utility, allowing access to Samba (SMB, CIFS) shares from Ruby. What’s special about Sambala’s implementation, is that it allows for both both queue and interactive commands operations. While interactive mode is invoked in a blocking manner, the queue mode behaves as a non-blocking, multi-threaded, background process.

Sambala works on Unix derivatives operating systems (Linux, BSD, OSX, else), as long as the operating system has the smbclient utility installed somewhere in the environment’s PATH.

Sambala supports most, but not all, smbclient features. I didn’t to this point implement commands relying on posix server support, because I wanted Sambala to be server agnostic. If some commands or interfaces you would like to use is not supported by Sambala, email me and I may answer with a quick feature update when feasible.

I tried to make Sambala as simple as possible, retaining most of the original smbclient command names, as instance method names for the Sambala client object. It behaves as you would expect from an OOP lib: You instantiate a new Sambala object and are then allowed to send smbclient commands a instance method to this object. The only big difference, is the queue mode, which is activated on a per command/method invocation, with a ‘true’ flag, you add as the last parameter to the method invocation. When some commands are queued, you can harvest them at a later point with the queue_results method, returning an array containing your commands and their respective results.

When in doubt about what each command does, please refer to smbclient man page for help. ///////////////////////////////////////////////////////////////////////////////////////

Example:

samba = Sambala.new(  :domain   =>  'NTDOMAIN', 
                    :host     =>  'sambaserver',
                    :share    =>  'sambashare',
                    :user     =>  'walrus', 
                    :password =>  'eggman')

samba.cd('myfolder')   # =>  true
samba.put(:from => 'aLocalFile.txt')    # =>  [false, "aLocalFile.txt does not exist\r\n"]

For detailed documentation refer to the online ruby-doc: sambala.rubyforge.org/ruby-doc/

///////////////////////////////////////////////////////////////////////////////////////

Author

lp ([email protected])

Copyright

2008 Louis-Philippe Perron - Released under the terms of the MIT license

:title:Sambala

Defined Under Namespace

Modules: Gardener Classes: SmbInitError

Instance Method Summary collapse

Methods included from Gardener

#clean_path, #exec_interactive, #exec_queue, #execute, #gardener_ok, #init_gardener, #parse_results

Constructor Details

#initialize(options = {:domain => '', :host => '', :share => '', :user => '', :password => ''}) ⇒ Sambala

The new class method initializes Sambala.

Parameters

  • :domain = the smb server domain, optionnal in most cases

  • :host = the hostname of the smb server, may be IP or fully qualified domain name

  • :user = the user name to log into the server

  • :password = the password to log into the server

Example

samba = Sambala.new(  :domain   =>  'NTDOMAIN', 
                    :host     =>  'sambaserver',
                    :share    =>  'sambashare',
                    :user     =>  'walrus', 
                    :password =>  'eggman')


68
69
70
71
72
73
74
75
76
77
# File 'lib/sambala.rb', line 68

def initialize(options={:domain => '', :host => '', :share => '', :user => '', :password => ''})
  $log_sambala = GlobaLog.logger(STDERR,:warn)
begin
    options[:init_timeout] = 1
    @options = options; gardener_ok
  rescue
    @gardener.close unless @gardener.nil? || @gardener.class != 'Gardener'
    raise RuntimeError.exception("Unknown Process Failed!! (#{$!.to_s})")
  end
end

Instance Method Details

#cd(to = '.') ⇒ Object

The cd instance method takes only one argument, the path to which you wish to change directory

Parameters

  • to = the path to change directory to

Interactive Returns

  • boolean = confirms if cd operation completed successfully

Example

samba.cd('aFolder/anOtherFolder/')   # =>  true


86
87
88
# File 'lib/sambala.rb', line 86

def cd(to='.')
execute('cd',clean_path(to))[0]
end

#closeObject

The close method safely end the smbclient session

Example

samba.close


322
323
324
325
# File 'lib/sambala.rb', line 322

def close
  result = @gardener.close
  result.values.map { |queue| queue.empty? }.uniq.size == 1 ? true : false
end

#del(mask, queue = false) ⇒ Object Also known as: rm

The del instance method delete files on smb shares

Parameters

  • mask = the mask matching the file to be deleted inside the current working directory.

  • queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

  • boolean = confirms if del operation completed successfully

Example

samba.del('aFile')   # =>  true


108
109
110
# File 'lib/sambala.rb', line 108

def del(mask, queue=false)
  execute('del', mask, queue)[0]
end

#duObject

The du instance method does exactly what du usually does: estimates file space usage.

Interactive Returns

  • string = du command results

Example

puts samba.du   # =>  34923 blocks of size 2097152. 27407 blocks available
                    Total number of bytes: 59439077


96
97
98
# File 'lib/sambala.rb', line 96

def du
  execute('du', '', false)[1]
end

#exist?(mask) ⇒ Boolean

The exist? instance method is borrowed from Ruby File Class idiome. It is used to test the presence of files or directories on the server

Parameters

  • mask = the mask matching the file or directory to look for.

Interactive Returns

  • boolean = confirm the presence of a matching file or directory

Example

samba.exist?('aFile')  # => true

Returns:

  • (Boolean)


120
121
122
# File 'lib/sambala.rb', line 120

def exist?(mask)
  execute('ls', mask, false)[0]
end

#get(opts = {:from => nil, :to => nil, :queue => false}) ⇒ Object

The get instance method copy files from smb shares. As with the smbclient get command, the destination path is optional.

Parameters

  • :from = the source path, relative path to the current working directory in the smb server

  • :to = the destination path, absolute or relative path to the current working directory in the local OS

  • :queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

array = [ booleanSuccess, getResultMessage ]

Example

samba.get(:from => 'aFile.txt')   # => [true, "getting file \\aFile.txt.rb of size 3877 as test.rb (99.6 kb/s) (average 89.9 kb/s)\r\n"]


134
135
136
137
# File 'lib/sambala.rb', line 134

def get(opts={:from => nil, :to => nil, :queue => false})
  opts[:to].nil? ? strng = opts[:from] : strng = clean_path(opts[:from]) + ' ' + opts[:to]
  execute('get', strng, opts[:queue])
end

#lcd(to = '.') ⇒ Object

The lcd instance method changes the current working directory on the local machine to the directory specified.

Parameters

  • to = the path to change directory to

Interactive Returns

  • boolean = confirms if cd operation completed successfully

Example

samba.lcd('aLocalFolder/anOtherFolder/')   # => true


146
147
148
# File 'lib/sambala.rb', line 146

def lcd(to='.')
execute('lcd', to)[0]
end

#lowercaseObject

The lowercase method toggles lowercasing of filenames for the get command. Can be usefull when copying files from DOS servers. This method has no queue processing option

Interactive Returns

  • boolean = confirms if lowercase operation completed successfully

Example

samba.lowercase   # => true      # toggle from files all UPPERCASE to all lowercase


157
158
159
# File 'lib/sambala.rb', line 157

def lowercase
  execute('lowercase' ,'')[0]
end

#ls(mask = '') ⇒ Object Also known as: dir

The method ls or its alias dir, list the files and directories matching :mask in the current working directory on the smb server.

Parameters

  • mask = the mask matching the file to be listed inside the current working directory.

Interactive Returns

  • string = containing ls command results

Example

samba.ls  # =>  genpi.rb                            A       81  Mon Nov 17 22:12:40 2008
                  34923 blocks of size 2097152. 27407 blocks available


169
170
171
# File 'lib/sambala.rb', line 169

def ls(mask='')
  execute('ls' ,mask, false)[1]
end

#mask(mask) ⇒ Object

The mask method sets a mask to be used during recursive operation of the mget and mput commands. See man page for smbclient to get more on the details of operation This method has no queue processing option

Parameters

  • mask = the matching filter

Example

samba.mask('filter*')  # => true


181
182
183
# File 'lib/sambala.rb', line 181

def mask(mask)
  execute('mask' ,mask)[0]
end

#mget(mask, queue = false) ⇒ Object

The mget method copy all files matching :mask from the server to the client machine See man page for smbclient to get more on the details of operation

Parameters

  • mask = the file matching filter

  • queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

array = [ booleanSuccess, mgetResultMessage ]

Example

samba.mget('file*')  # => [true, "getting file \\file_new.txt of size 3877 as file_new.txt (99.6 kb/s) (average 89.9 kb/s)\r\n"]


194
195
196
# File 'lib/sambala.rb', line 194

def mget(mask,queue=false)
  execute('mget' ,mask, queue)
end

#mkdir(path, queue = false) ⇒ Object Also known as: md

The method mkdir or its alias md, creates a new directory on the server.

Parameters

  • path = the directory to create

  • queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

  • boolean = confirms if mkdir operation completed successfully

Example

samba.mkdir('aFolder/aNewFolder')  # => true


206
207
208
# File 'lib/sambala.rb', line 206

def mkdir(path, queue=false)
  execute('mkdir' , clean_path(path), queue)[0]
end

#mput(mask, queue = false) ⇒ Object

The mput method copy all files matching :mask in the current working directory on the local machine to the server. See man page for smbclient to get more on the details of operation

Parameters

  • mask = the file matching filter

  • queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

array = [ booleanSuccess, mputResultMessage ]

Example

samba.mput('file*')  # =>  [true, "putting file \\file_new.txt of size 1004 as file_new.txt (65.4 kb/s) (average 65.4 kb/s)\r\n"]


220
221
222
# File 'lib/sambala.rb', line 220

def mput(mask, queue=false)
  execute('mput' ,mask, queue)
end

#progressObject

The progress method returns a progress ratio indicator from 0.00 to 1.00

Example

progress = samba.progress   # => 0.75


315
316
317
# File 'lib/sambala.rb', line 315

def progress
  @gardener.growth(:progress)
end

#put(opts = {:from => nil, :to => nil, :queue => false}) ⇒ Object

The put instance method copy files to smb shares. As with the smbclient put command, the destination path is optional.

Parameters

  • :from = the source path, absolute or relative path to the current working directory in the local OS

  • :to = the destination path, relative path to the current working directory in the smb server OS

  • :queue = sets queue processing mode. Defaults to interactive mode when no option given.

Interactive Returns

array = [ booleanSuccess, putResultMessage ]

Example

samba.put(:from => 'aLocalFile.txt')   # =>  [false, "aLocalFile.txt does not exist\r\n"]


235
236
237
238
# File 'lib/sambala.rb', line 235

def put(opts={:from => nil, :to => nil, :queue => false})
  opts[:to].nil? ? strng = opts[:from] : strng = opts[:from] + ' ' + clean_path(opts[:to])
  execute('put' , strng, opts[:queue])
end

#queue_completedObject

The queue_completed method returns an array containing the task that have completed



287
288
289
# File 'lib/sambala.rb', line 287

def queue_completed
	parse_results(@gardener.harvest(:crop))
end

#queue_done?Boolean

The queue_done? method return true if all jobs have finished processing

Example

samba.queue_done? # true

Returns:

  • (Boolean)


301
302
303
# File 'lib/sambala.rb', line 301

def queue_done?
	@gardener.growth(:finished)
end

#queue_empty?Boolean

The queue_empty? method return true if there are no jobs in queue

Example

samba.queue_empty? # false

Returns:

  • (Boolean)


294
295
296
# File 'lib/sambala.rb', line 294

def queue_empty?
	@gardener.growth(:empty)
end

#queue_processingObject

The queue_processing method returns an array containing the tasks actually processing

Example

samba.queue_processing # => [[1, “put myFile”],[2, “put lib/sambala.rb sambala.rb”]]



281
282
283
284
# File 'lib/sambala.rb', line 281

def queue_processing
	results = @gardener.harvest(:sprout)
	results.map { |result| [result[:id], result[:seed]] }
end

#queue_resultsObject

The queue_results methods wait for all queued items to finish and returns them.

Example

result = samba.queue_results


308
309
310
# File 'lib/sambala.rb', line 308

def queue_results
  parse_results(@gardener.harvest(:full_crop))
end

#queue_waitingObject

The queue_waiting method returns the number of waiting task in queue

Example

samba.queue_waiting # => 3



274
275
276
# File 'lib/sambala.rb', line 274

def queue_waiting
	@gardener.growth(:seed)
end

#recurseObject

The recurse method toggles directory recursion This method has no queue processing option

Interactive Returns

  • boolean = confirms if mkdir operation completed successfully

Example

samba.recurse   # => true


246
247
248
# File 'lib/sambala.rb', line 246

def recurse
  execute('recurse' ,'')[0]
end

#rmdir(path, queue = false) ⇒ Object

samba.rmdir(‘mydir’) # => true



258
259
260
# File 'lib/sambala.rb', line 258

def rmdir(path,queue=false)
	execute('rmdir' , clean_path(path), queue)[0]
end

#volumeObject

The volume method returns remote volume information.

Interactive Returns

  • string = containing volume command results

Example

samba.volume  # => "Volume: |geminishare| serial number 0x6d723053"


267
268
269
# File 'lib/sambala.rb', line 267

def volume
  execute('volume' ,'', false)[1]
end