Class: RubySMB::Server::Share::Provider::VirtualDisk

Inherits:
Disk
  • Object
show all
Defined in:
lib/ruby_smb/server/share/provider/virtual_disk.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_file.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_stat.rb,
lib/ruby_smb/server/share/provider/virtual_disk/virtual_pathname.rb

Overview

This is a share provider that exposes a virtual file system whose entries do not exist on disk.

Since:

  • 3.1.1

Defined Under Namespace

Classes: VirtualDynamicFile, VirtualMappedFile, VirtualPathname, VirtualStat, VirtualStaticFile

Constant Summary

Constants inherited from Disk

Disk::FILE_SYSTEM, Disk::TYPE

Instance Attribute Summary

Attributes inherited from Disk

#path

Attributes inherited from Base

#hooks, #name

Instance Method Summary collapse

Methods inherited from Base

#add_hook, #remove_hook, #type

Constructor Details

#initialize(name, hooks: nil) ⇒ VirtualDisk

Returns a new instance of VirtualDisk.

Parameters:

  • name (String)

    The name of this share.

Since:

  • 3.1.1



17
18
19
20
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 17

def initialize(name, hooks: nil)
  @vfs = {}
  super(name, add(VirtualPathname.new(self, File::SEPARATOR)), hooks: hooks)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) ⇒ Object (private)

Raises:

  • (NoMethodError)

Since:

  • 3.1.1



101
102
103
104
105
106
107
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 101

def method_missing(symbol, *args)
  if HASH_METHODS.include?(symbol)
    return @vfs.send(symbol, *args)
  end

  raise NoMethodError, "undefined method `#{symbol}' for #{self.class}"
end

Instance Method Details

#add(virtual_pathname) ⇒ Object

Raises:

  • (ArgumentError)

Since:

  • 3.1.1



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 71

def add(virtual_pathname)
  raise ArgumentError.new('paths must be absolute') unless virtual_pathname.absolute?

  path = virtual_pathname.to_s
  raise ArgumentError.new('paths must be normalized') unless VirtualPathname.cleanpath(path) == path

  path_parts = path.split(VirtualPathname::SEPARATOR)
  2.upto(path_parts.length - 1) do |idx|
    ancestor = path_parts[0...idx].join(path[VirtualPathname::SEPARATOR])
    next if @vfs[ancestor]&.directory?

    @vfs[ancestor] = VirtualPathname.new(self, ancestor, stat: VirtualStat.new(directory?: true))
  end

  @vfs[path] = virtual_pathname
end

#add_dynamic_file(path, stat: nil) { ... } ⇒ Object

Add a dynamic file to the virtual file system. A dynamic file is one whose contents are generated by the specified block. The contents are generated when the share is opened.

Parameters:

  • path (String)

    The path of the file to add, relative to the share root.

  • stat (File::Stat) (defaults to: nil)

    An explicit stat object describing the file.

Yields:

  • The content generation routine.

Yield Returns:

  • (String)

    The generated file content.

Raises:

  • (ArgumentError)

Since:

  • 3.1.1



29
30
31
32
33
34
35
36
37
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 29

def add_dynamic_file(path, stat: nil, &block)
  raise ArgumentError.new('a block must be specified for dynamic files') unless block_given?
  path = VirtualPathname.cleanpath(path)
  path = File::SEPARATOR + path unless path.start_with?(File::SEPARATOR)
  raise ArgumentError.new('must be a file') if stat && !stat.file?

  vf = VirtualDynamicFile.new(self, path, stat: stat, &block)
  add(vf)
end

#add_mapped_file(path, mapped_path) ⇒ Object

Add a mapped file to the virtual file system. A mapped file is one who is backed by an entry on disk. The path need not be present, but if it does exist, it must be a file.

Parameters:

  • path (String)

    The path of the file to add, relative to the share root.

  • mapped_path (String, Pathname)

    The path on the local file system to map into the virtual file system.

Since:

  • 3.1.1



44
45
46
47
48
49
50
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 44

def add_mapped_file(path, mapped_path)
  path = VirtualPathname.cleanpath(path)
  path = File::SEPARATOR + path unless path.start_with?(File::SEPARATOR)

  vf = VirtualMappedFile.new(self, path, mapped_path)
  add(vf)
end

#add_static_file(path, content, stat: nil) ⇒ Object

Add a static file to the virtual file system. A static file is one whose contents are known at creation time and do not change. If content is a file-like object that responds to #read, the data will be read using that method. Likewise, if content has a #stat attribute and stat was not specified, then the value of content's #stat attribute will be used.

Parameters:

  • path (String)

    The path of the file to add, relative to the share root.

  • content (String, #read, #stat)

    The static content to add.

  • stat (File::Stat) (defaults to: nil)

    An explicit stat object describing the file.

Raises:

  • (ArgumentError)

Since:

  • 3.1.1



60
61
62
63
64
65
66
67
68
69
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 60

def add_static_file(path, content, stat: nil)
  path = VirtualPathname.cleanpath(path)
  path = File::SEPARATOR + path unless path.start_with?(File::SEPARATOR)
  raise ArgumentError.new('must be a file') if stat && !stat.file?

  stat = content.stat if content.respond_to?(:stat) && stat.nil?
  content = content.read if content.respond_to?(:read)
  vf = VirtualStaticFile.new(self, path, content, stat: stat)
  add(vf)
end

#new_processor(server_client, session) ⇒ Object

Since:

  • 3.1.1



88
89
90
91
92
93
94
95
96
97
# File 'lib/ruby_smb/server/share/provider/virtual_disk.rb', line 88

def new_processor(server_client, session)
  scoped_virtual_disk = self.class.new(@name, hooks: @hooks)
  @vfs.each_value do |path|
    path = path.dup
    path.virtual_disk = scoped_virtual_disk if path.is_a?(VirtualPathname)
    path = path.generate(server_client, session) if path.is_a?(VirtualDynamicFile)
    scoped_virtual_disk.add(path)
  end
  self.class::Processor.new(scoped_virtual_disk, server_client, session)
end