Module: Iso9660
- Included in:
- FileObject
- Defined in:
- lib/fs/iso9660/util.rb,
lib/fs/iso9660/directory.rb,
lib/fs/iso9660/file_data.rb,
lib/fs/iso9660/rock_ridge.rb,
lib/fs/iso9660/boot_sector.rb,
lib/fs/MiqFS/modules/Iso9660.rb,
lib/fs/iso9660/directory_entry.rb
Defined Under Namespace
Modules: Util Classes: AlternateName, BootSector, Directory, DirectoryEntry, Extension, FileData, FileObject, PosixAttributes, RockRidge, SparseFile, SymbolicLink
Constant Summary collapse
- RR_SIGNATURE =
NOTE: This implementation is sufficient for Rock Ridge extensions. It will not identify or process any other System Use Sharing Protocol extensions. In particular, SUSP CE (continuation area) records are not processed. This is where the “RR” extension is defined. This implementation uses the assumed definition RR_HEADER.
"RR"
- RR_HEADER =
BinaryStruct.new([ 'a2', 'signature', # RR if Rock Ridge. 'C', 'unused1', # ? always seems to be 5. 'C', 'unused2', # ? always seems to be 1 (version?). 'C', 'unused3' # ? 0x81 ])
- RR_HEADER_SIZE =
5
- RR_PN_SIGNATURE =
These types are not used, but we want to know if they pop up.
"PN"
- RR_CL_SIGNATURE =
"CL"
- RR_PL_SIGNATURE =
"PL"
- RR_RE_SIGNATURE =
"RE"
- RR_TF_SIGNATURE =
"TF"
- RR_PX_SIGNATURE =
POSIX file attributes. See POSIX 5.6.1.
"PX"
- RR_PX =
BinaryStruct.new([ 'L', 'modeLE', # file mode (used to identify a link). 'L', 'modeBE', 'L', 'linksLE', # Num links (st_nlink). 'L', 'linksBE', 'L', 'userLE', # User ID. 'L', 'userBE', 'L', 'groupLE', # Group ID. 'L', 'groupBE' # 'L', 'serialLE', # File serial number. # 'L', 'serialBE' ])
- RR_EXT_SL_FM_SOCK =
File mode bits.
0xc000
- RR_EXT_SL_FM_LINK =
0xa000
- RR_EXT_SL_FM_FILE =
0x8000
- RR_EXT_SL_FM_BLOK =
0x6000
- RR_EXT_SL_FM_CHAR =
0x2000
- RR_EXT_SL_FM_DIR =
0x4000
- RR_EXT_SL_FM_FIFO =
0x1000
- RR_SL_SIGNATURE =
Symbolic link.
"SL"
- RR_SL =
BinaryStruct.new([ 'C', 'flags', # See RR_EXT_SLF_ below. 'a*', 'components' ])
- RR_EXT_SLF_CONTINUE =
Symbolic link flags.
0x01
- RR_SL_COMPONENT =
A symbolic link component record.
BinaryStruct.new([ 'C', 'flags', # See RR_EXT_SLCOMPF_ below. 'C', 'length', # Length of content in bytes. 'a*', 'content' ])
- RR_EXT_SLCOMPF_CONTINUE =
Component continues in the next component record.
0x01
- RR_EXT_SLCOMPF_CURRENT =
Component refers to the current directory.
0x02
- RR_EXT_SLCOMPF_PARENT =
Component refers to the parent directory.
0x04
- RR_EXT_SLCOMPF_ROOT =
Component refers to the root directory.
0x08
- RR_EXT_SLCOMPF_RESERVED1 =
See below.
0x10
- RR_EXT_CLCOMPF_RESERVED2 =
See below.
0x20
- RR_NM_SIGNATURE =
Alternate name.
"NM"
- RR_NM =
BinaryStruct.new([ 'C', 'flags', # See RR_EXT_NMF_ below. 'a*', 'content' ])
- RR_EXT_NMF_CONTINUE =
NOTE: These flag bits are mutually exclusive.
0x01
- RR_EXT_NMF_CURRENT =
Name continues in the next NM entry.
0x02
- RR_EXT_NMF_PARENT =
Name refers to the current directory.
0x04
- RR_EXT_NMF_RESERVED1 =
Name refers to the parent directory.
0x08
- RR_EXT_NMF_RESERVED2 =
Reserved - 0.
0x10
- RR_EXT_NMF_RESERVED3 =
Reserved - 0.
0x20
- RR_SF_SIGNATURE =
Sparse File.
"SF"
- RR_SF =
BinaryStruct.new([ 'L', 'size_hiLE', 'L', 'size_hiBE', 'L', 'size_loLE', 'L', 'size_loBE', 'C', 'table_depth', ])
- RR_EXT_HEADER =
Common to all RR extensions.
BinaryStruct.new([ 'a2', 'signature', # Extension type. 'C', 'length', # length in bytes. 'C', 'version' # Entry version, always 1. ])
- RR_EXT_HEADER_SIZE =
4
- DEF_CACHE_SIZE =
Default cache size.
50
- PRIMARY_SECTOR =
16
- JOLIET_SECTOR =
17
- SECTOR_SIZE =
2048
- FB_HIDDEN =
FlagBits: FB_
0x01
- FB_DIRECTORY =
0 if not hidden.
0x02
- FB_ASSOCIATED =
0 if file.
0x04
- FB_RFS =
0 if not ‘associated’ (?)
0x08
- FB_PS =
RecordFormatSpecified: 0 if not.
0x10
- FB_UNUSED1 =
PermissionsSpecified: 0 if not.
0x20
- FB_UNUSED2 =
No info.
0x40
- FB_NOT_LAST =
No info.
0x80
- EXT_NONE =
Extensions.
0
- EXT_JOLIET =
1
- EXT_ROCKRIDGE =
2
Instance Attribute Summary collapse
-
#boot_sector ⇒ Object
Members (these become members of an MiqFS instance).
-
#cache_hits ⇒ Object
Members (these become members of an MiqFS instance).
-
#dir_cache ⇒ Object
Members (these become members of an MiqFS instance).
-
#drive_root ⇒ Object
Members (these become members of an MiqFS instance).
Instance Method Summary collapse
-
#fs_dirEntries(p) ⇒ Object
Returns String array of all names, sans path.
-
#fs_dirMkdir(_p) ⇒ Object
These two are not implemented.
-
#fs_dirRmdir(_p) ⇒ Object
Remove a directory.
-
#fs_fileAtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileAtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
-
#fs_fileClose(_fobj) ⇒ Object
Destroy file object.
-
#fs_fileCtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileCtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
-
#fs_fileDelete(_p) ⇒ Object
Delete file.
-
#fs_fileDirectory?(p) ⇒ Boolean
Returns true if name is a directory.
-
#fs_fileExists?(p) ⇒ Boolean
Returns true if name exists, false if not.
-
#fs_fileFile?(p) ⇒ Boolean
Returns true if name is a regular file.
-
#fs_fileMtime(p) ⇒ Object
Returns Ruby Time object.
-
#fs_fileMtime_obj(fobj) ⇒ Object
Returns a Ruby Time obect.
-
#fs_fileOpen(p, mode = "r") ⇒ Object
New FileObject instance.
-
#fs_fileRead(fobj, len) ⇒ Object
Returns a Ruby String object.
-
#fs_fileSeek(fobj, offset, whence) ⇒ Object
Returns current file position.
-
#fs_fileSize(p) ⇒ Object
Returns size in bytes.
-
#fs_fileSize_obj(fobj) ⇒ Object
In these, fobj is a FileObject.
- #fs_fileWrite(_fobj, _buf, _len) ⇒ Object
-
#fs_freeBytes ⇒ Object
Returns free space on file system in bytes.
- #fs_init ⇒ Object
-
#fs_isSymLink?(p) ⇒ Boolean
Return true if p is a path to a symbolic link.
-
#ifs_getDir(p, miqfs = nil) ⇒ Object
Return a Directory object for a path.
-
#ifs_getFile(p, miqfs = nil) ⇒ Object
Return a DirectoryEntry for a given file or nil if not exist.
-
#unnormalizePath(p) ⇒ Object
Wack leading drive leter & colon.
Instance Attribute Details
#boot_sector ⇒ Object
Members (these become members of an MiqFS instance).
18 19 20 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 18 def boot_sector @boot_sector end |
#cache_hits ⇒ Object
Members (these become members of an MiqFS instance).
18 19 20 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 18 def cache_hits @cache_hits end |
#dir_cache ⇒ Object
Members (these become members of an MiqFS instance).
18 19 20 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 18 def dir_cache @dir_cache end |
#drive_root ⇒ Object
Members (these become members of an MiqFS instance).
18 19 20 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 18 def drive_root @drive_root end |
Instance Method Details
#fs_dirEntries(p) ⇒ Object
Returns String array of all names, sans path.
94 95 96 97 98 99 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 94 def fs_dirEntries(p) # Get path directory. dir = ifs_getDir(p) return nil if dir.nil? dir.globNames end |
#fs_dirMkdir(_p) ⇒ Object
These two are not implemented.
102 103 104 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 102 def fs_dirMkdir(_p) raise "Write functionality is not supported on Iso9660." end |
#fs_dirRmdir(_p) ⇒ Object
Remove a directory.
107 108 109 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 107 def fs_dirRmdir(_p) raise "Write functionality is not supported on Iso9660." end |
#fs_fileAtime(p) ⇒ Object
Returns Ruby Time object.
149 150 151 152 153 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 149 def fs_fileAtime(p) de = ifs_getFile(p) return nil if de.nil? de.date end |
#fs_fileAtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
182 183 184 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 182 def fs_fileAtime_obj(fobj) fobj.de.date end |
#fs_fileClose(_fobj) ⇒ Object
Destroy file object.
221 222 223 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 221 def fs_fileClose(_fobj) fobj = nil end |
#fs_fileCtime(p) ⇒ Object
Returns Ruby Time object.
156 157 158 159 160 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 156 def fs_fileCtime(p) de = ifs_getFile(p) return nil if de.nil? de.date end |
#fs_fileCtime_obj(fobj) ⇒ Object
Returns a Ruby Time object.
187 188 189 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 187 def fs_fileCtime_obj(fobj) fobj.de.date end |
#fs_fileDelete(_p) ⇒ Object
Delete file.
144 145 146 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 144 def fs_fileDelete(_p) raise "Write functionality is not supported on Iso9660." end |
#fs_fileDirectory?(p) ⇒ Boolean
Returns true if name is a directory.
130 131 132 133 134 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 130 def fs_fileDirectory?(p) de = ifs_getFile(p) return false if de.nil? de.isDir? end |
#fs_fileExists?(p) ⇒ Boolean
Returns true if name exists, false if not.
116 117 118 119 120 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 116 def fs_fileExists?(p) de = ifs_getFile(p) return false if de.nil? true end |
#fs_fileFile?(p) ⇒ Boolean
Returns true if name is a regular file.
123 124 125 126 127 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 123 def fs_fileFile?(p) de = ifs_getFile(p) return false if de.nil? de.isFile? end |
#fs_fileMtime(p) ⇒ Object
Returns Ruby Time object.
163 164 165 166 167 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 163 def fs_fileMtime(p) de = ifs_getFile(p) return nil if de.nil? de.date end |
#fs_fileMtime_obj(fobj) ⇒ Object
Returns a Ruby Time obect.
192 193 194 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 192 def fs_fileMtime_obj(fobj) fobj.de.date end |
#fs_fileOpen(p, mode = "r") ⇒ Object
New FileObject instance. NOTE: FileObject must have access to Iso9660 members. This is kind of like a ‘skip this’ thing. Ext3 methods use stuff owned by MiqFS, so this is necessary.
200 201 202 203 204 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 200 def fs_fileOpen(p, mode = "r") fobj = FileObject.new(p, self) fobj.open(mode) fobj end |
#fs_fileRead(fobj, len) ⇒ Object
Returns a Ruby String object.
212 213 214 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 212 def fs_fileRead(fobj, len) fobj.data.read(len) end |
#fs_fileSeek(fobj, offset, whence) ⇒ Object
Returns current file position.
207 208 209 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 207 def fs_fileSeek(fobj, offset, whence) fobj.data.seek(offset, whence) end |
#fs_fileSize(p) ⇒ Object
Returns size in bytes.
137 138 139 140 141 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 137 def fs_fileSize(p) de = ifs_getFile(p) return nil if de.nil? de.fileSize end |
#fs_fileSize_obj(fobj) ⇒ Object
In these, fobj is a FileObject.
177 178 179 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 177 def fs_fileSize_obj(fobj) fobj.de.fileSize end |
#fs_fileWrite(_fobj, _buf, _len) ⇒ Object
216 217 218 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 216 def fs_fileWrite(_fobj, _buf, _len) raise "Write functionality is not supported on Iso9660." end |
#fs_freeBytes ⇒ Object
Returns free space on file system in bytes.
85 86 87 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 85 def fs_freeBytes 0 end |
#fs_init ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 46 def fs_init self.fsType = "ISO9660" # Start by looking for a Joliet volume descriptor after the primary descriptor. found_joliet = false @dobj.seek(JOLIET_SECTOR * SECTOR_SIZE) begin @boot_sector = BootSector.new(@dobj, true) found_joliet = true rescue end # If Joliet wasn't found, look for a primary descriptor. unless found_joliet found_primary = false @dobj.seek(PRIMARY_SECTOR * SECTOR_SIZE) loop do begin @boot_sector = BootSector.new(@dobj) found_primary = true break rescue end end raise "Iso9660#fs_init couldn't find primary descriptor." unless found_primary end # Set volume id. # @fsId = ... hmmm, how to get the serial number. @volName = @boot_sector.volName # Init cache & root. self.dir_cache = LruHash.new(DEF_CACHE_SIZE) self.cache_hits = 0 de = DirectoryEntry.new(@boot_sector.rootEntry, @boot_sector.suff) self.drive_root = Directory.new(@boot_sector, de) end |
#fs_isSymLink?(p) ⇒ Boolean
Return true if p is a path to a symbolic link.
170 171 172 173 174 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 170 def fs_isSymLink?(p) de = ifs_getFile(p) return false if de.nil? de.isSymLink? end |
#ifs_getDir(p, miqfs = nil) ⇒ Object
Return a Directory object for a path. Raise error if path doesn’t exist.
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 254 def ifs_getDir(p, miqfs = nil) # If this is being called from a FileObject instance, then MiqFS owns contained instance members. # If this is being called from an Ext3 module method, then self owns contained instance members. miqfs = self if miqfs.nil? # Wack leading drive. p = unnormalizePath(p) # Check for this path in the cache. if miqfs.dir_cache.key?(p) miqfs.cache_hits += 1 return Directory.new(miqfs.boot_sector, DirectoryEntry.new(miqfs.dir_cache[p], miqfs.boot_sector.suff)) end # Return root if lone separator. return miqfs.drive_root if p == "/" || p == "\\" # Get an array of directory names, kill off the first (it's always empty). names = p.split(/[\\\/]/); names.shift # Find target dir. de = miqfs.drive_root.myEnt loop do break if names.empty? dir = Directory.new(miqfs.boot_sector, de) de = dir.findEntry(names.shift, Directory::FE_DIR) raise "Can't find directory: \'#{p}\'" if de.nil? end # Save dir ent in the cache & return a Directory. # NOTE: This stores only the directory entry data string - not the whole object. miqfs.dir_cache[p] = de.myEnt Directory.new(miqfs.boot_sector, de) end |
#ifs_getFile(p, miqfs = nil) ⇒ Object
Return a DirectoryEntry for a given file or nil if not exist.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 228 def ifs_getFile(p, miqfs = nil) # If this is being called from a FileObject instance, then MiqFS owns contained instance members. # If this is being called from an Ext3 module method, then self owns contained instance members. miqfs = self if miqfs.nil? # Preprocess path. p = unnormalizePath(p) dir, fil = File.split(p) # Fix for FB#835: if fil == root then fil needs to be "." fil = "." if fil == "/" || fil == "\\" # Look for file in dir, but don't barf if it doesn't exist. # NOTE: if p is a directory that's ok, find it. begin dirObj = ifs_getDir(dir, miqfs) return nil if dirObj.nil? dirEnt = dirObj.findEntry(fil) return nil if dirEnt.nil? rescue RuntimeError return nil end dirEnt end |
#unnormalizePath(p) ⇒ Object
Wack leading drive leter & colon.
290 291 292 |
# File 'lib/fs/MiqFS/modules/Iso9660.rb', line 290 def unnormalizePath(p) p[1] == 58 ? p[2, p.size] : p end |