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', 
                    :threads  =>  2 )

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, #execute_all, #gardener_ok, #init_gardener, #parse_results

Constructor Details

#initialize(options = {:domain => '', :host => '', :share => '', :user => '', :password => '', :threads => 1}) ⇒ 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

  • :threads = how many parallel operations you want initiated, !!! higher than 4 at you own risk !!!

Example

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


71
72
73
74
75
76
77
78
79
80
81
# File 'lib/sambala.rb', line 71

def initialize(options={:domain => '', :host => '', :share => '', :user => '', :password => '', :threads => 1})
  $log_sambala = GlobaLog.logger(STDERR,:warn)
begin
    options[:threads] = 4 if options[:threads] > 4
    options[:init_timeout] = options[:threads]
    @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


90
91
92
# File 'lib/sambala.rb', line 90

def cd(to='.')
execute_all('cd',clean_path(to))
end

#closeObject

The close method safely end the smbclient session

Example

samba.close


326
327
328
329
# File 'lib/sambala.rb', line 326

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


112
113
114
# File 'lib/sambala.rb', line 112

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


100
101
102
# File 'lib/sambala.rb', line 100

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)


124
125
126
# File 'lib/sambala.rb', line 124

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"]


138
139
140
141
# File 'lib/sambala.rb', line 138

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


150
151
152
# File 'lib/sambala.rb', line 150

def lcd(to='.')
execute_all('lcd', to)
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


161
162
163
# File 'lib/sambala.rb', line 161

def lowercase
  execute_all('lowercase' ,'')
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


173
174
175
# File 'lib/sambala.rb', line 173

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


185
186
187
# File 'lib/sambala.rb', line 185

def mask(mask)
  execute_all('mask' ,mask)
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"]


198
199
200
# File 'lib/sambala.rb', line 198

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


210
211
212
# File 'lib/sambala.rb', line 210

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"]


224
225
226
# File 'lib/sambala.rb', line 224

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


319
320
321
# File 'lib/sambala.rb', line 319

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"]


239
240
241
242
# File 'lib/sambala.rb', line 239

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



291
292
293
# File 'lib/sambala.rb', line 291

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)


305
306
307
# File 'lib/sambala.rb', line 305

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)


298
299
300
# File 'lib/sambala.rb', line 298

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”]]



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

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


312
313
314
# File 'lib/sambala.rb', line 312

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



278
279
280
# File 'lib/sambala.rb', line 278

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


250
251
252
# File 'lib/sambala.rb', line 250

def recurse
  execute_all('recurse' ,'')
end

#rmdir(path, queue = false) ⇒ Object

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



262
263
264
# File 'lib/sambala.rb', line 262

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"


271
272
273
# File 'lib/sambala.rb', line 271

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