Documentation ¶
Overview ¶
Package iso9660 implements ECMA-119 standard, also known as ISO 9660.
References:
* https://en.wikipedia.org/wiki/ISO_9660
* http://alumnus.caltech.edu/~pje/iso9660.html
* http://users.telenet.be/it3.consultants.bvba/handouts/ISO9960.html
* http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
* http://www.drdobbs.com/database/inside-the-iso-9660-filesystem-format/184408899
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrInvalidImage is returned when an attempt to unpack the image Primary Volume Descriptor failed or // when the end of the image was reached without finding a primary volume descriptor ErrInvalidImage = func(err error) error { return fmt.Errorf("invalid-iso9660-image: %s", err) } // ErrCorruptedImage is returned when a seek operation, on the image, failed. ErrCorruptedImage = func(err error) error { return fmt.Errorf("corrupted-image: %s", err) } )
Functions ¶
This section is empty.
Types ¶
type BootRecord ¶
type BootRecord struct { VolumeDescriptor SystemID [32]byte ID [32]byte SystemUse [1977]byte }
BootRecord identifies a system which can recognize and act upon the content of the field reserved for boot system use in the Boot Record, and shall contain information which is used to achieve a specific state for a system or for an application.
type DirectoryRecord ¶
type DirectoryRecord struct { // Extended Attribute Record length, stored at the beginning of // the file's extent. ExtendedAttrLen byte // Location of extent (Logical Block Address) in both-endian format. ExtentLocationLE uint32 ExtentLocationBE uint32 // Data length (size of extent) in both-endian format. ExtentLengthLE uint32 ExtentLengthBE uint32 // Date and the time of the day at which the information in the Extent // described by the Directory Record was recorded. RecordedTime [7]byte // If this Directory Record identifies a directory then bit positions 2, 3 // and 7 shall be set to ZERO. If no Extended Attribute Record is associated // with the File Section identified by this Directory Record then bit // positions 3 and 4 shall be set to ZERO. -- 9.1.6 FileFlags byte // File unit size for files recorded in interleaved mode, zero otherwise. FileUnitSize byte // Interleave gap size for files recorded in interleaved mode, zero otherwise. InterleaveGapSize byte // Volume sequence number - the volume that this extent is recorded on, in // 16 bit both-endian format. VolumeSeqNumberLE uint16 VolumeSeqNumberBE uint16 // Length of file identifier (file name). This terminates with a ';' // character followed by the file ID number in ASCII coded decimal ('1'). FileIDLength byte }
DirectoryRecord describes the characteristics of a file or directory, beginning with a length octet describing the size of the entire entry. Entries themselves are of variable length, up to 255 octets in size. Attributes for the file described by the directory entry are stored in the directory entry itself (unlike UNIX). The root directory entry is a variable length object, so that the name can be of variable length.
Important: before each entry there can be "fake entries" to support the Long File Name.
Even if a directory spans multiple sectors, the directory entries are not permitted to cross the sector boundary (unlike the path table). Where there is not enough space to record an entire directory entry at the end of a sector, that sector is zero-padded and the next consecutive sector is used. Unfortunately, the date/time format is different from that used in the Primary Volume Descriptor.
type ExtendedAttrRecord ¶
type ExtendedAttrRecord struct { OwnerID int `struc:"int16"` GroupID int `struc:"int16"` Permissions int `struc:"int16"` CreationTime Timestamp ModificationTime Timestamp ExpirationTime Timestamp // Specifies the date and the time of the day at which the information in // the file may be used. If the date and time are not specified then the // information may be used at once. EffectiveTime Timestamp Format int `struc:"uint8"` Attributes int `struc:"uint8"` Length int `struc:"int16"` SystemID string `struc:"[32]byte"` SystemUse [64]byte Version int `struc:"uint8"` EscapeSeqLength int `struc:"uint8"` Reserved [64]byte AppUseLength int `struc:"int16,sizeof=AppUse"` AppUse []byte EscapeSequences []byte `struc:"sizefrom=AppUseLength"` }
ExtendedAttrRecord are simply a way to extend the attributes of files. Since attributes vary according to the user, most everyone has a different opinion on what a file attribute should specify.
type File ¶
type File struct { DirectoryRecord // contains filtered or unexported fields }
File represents a concrete implementation of os.FileInfo interface for accessing ISO 9660 file data
type PartitionVolume ¶
type PartitionVolume struct { VolumeDescriptor Unused byte SystemID string `struc:"[32]byte"` ID string `struc:"[32]byte"` Location int `struc:"int8"` Size int `struc:"int8"` SystemUse [1960]byte }
PartitionVolume ...
type PathTable ¶
type PathTable struct { DirIDLength int `struc:"uint8,sizeof=DirName"` ExtendedAttrsLen int `struc:"uint8"` // Number the Logical Block Number of the first Logical Block allocated to // the Extent in which the directory is recorded. // This is in a different format depending on whether this is the L-Table or // M-Table (see explanation above). ExtentLocation int `struc:"int32"` // Number of record for parent directory (or 1 for the root directory), as a // word; the first record is number 1, the second record is number 2, etc. // Directory number of parent directory (an index in to the path table). // This is the field that limits the table to 65536 records. ParentDirNumber int `struc:"int16"` // Directory Identifier (name) in d-characters. DirName string }
PathTable contains a well-ordered sequence of records describing every directory extent on the CD. There are some exceptions with this: the Path Table can only contain 65536 records, due to the length of the "Parent Directory Number" field. If there are more than this number of directories on the disc, some CD authoring software will ignore this limit and create a non-compliant CD (this applies to some earlier versions of Nero, for example). If your file system uses the path table, you should be aware of this possibility. Windows uses the Path Table and will fail with such non-compliant CD's (additional nodes exist but appear as zero-byte). Linux, which uses the directory tables is not affected by this issue. The location of the path tables can be found in the Primary Volume Descriptor. There are two table types - the L-Path table (relevant to x86) and the M-Path table. The only difference between these two tables is that multi-byte values in the L-Table are LSB-first and the values in the M-Table are MSB-first.
The path table is in ascending order of directory level and is alphabetically sorted within each directory level.
type PrimaryVolume ¶
type PrimaryVolume struct { PrimaryVolumePart1 DirectoryRecord DirectoryRecord PrimaryVolumePart2 }
PrimaryVolume descriptor acts much like the superblock of the UNIX filesystem, providing details on the ISO-9660 compliant portions of the disk. While we can have many kinds of filesystems on a single ISO-9660 CD-ROM, we can have only one ISO-9660 file structure (found as the primary volume-descriptor type).
Directory entries are successively stored within this region. Evaluation of the ISO 9660 filenames is begun at this location. The root directory is stored as an extent, or sequential series of sectors, that contains each of the directory entries appearing in the root.
Since ISO 9660 works by segmenting the CD-ROM into logical blocks, the size of these blocks is found in the primary volume descriptor as well.
type PrimaryVolumePart1 ¶
type PrimaryVolumePart1 struct { VolumeDescriptor // The name of the system that can act upon sectors 0x00-0x0F for the volume. SystemID [32]byte // Identification of this volume. ID [32]byte // Amount of data available on the CD-ROM. Ignores little-endian order. // Takes big-endian encoded value. VolumeSpaceSizeLE int32 VolumeSpaceSizeBE int32 Unused2 [32]byte // The size of the set in this logical volume (number of disks). Ignores // little-endian order. Takes big-endian encoded value. VolumeSetSizeLE int16 VolumeSetSizeBE int16 // The number of this disk in the Volume Set. Ignores little-endian order. // Takes big-endian encoded value. VolumeSeqNumberLE int16 VolumeSeqNumberBE int16 // The size in bytes of a logical block. NB: This means that a logical block // on a CD could be something other than 2 KiB! LogicalBlkSizeLE int16 LogicalBlkSizeBE int16 // The size in bytes of the path table. Ignores little-endian order. // Takes big-endian encoded value. PathTableSizeLE int32 PathTableSizeBE int32 // LBA location of the path table. The path table pointed to contains only // little-endian values. LocPathTableLE int32 // LBA location of the optional path table. The path table pointed to contains // only little-endian values. Zero means that no optional path table exists. LocOptPathTableLE int32 // LBA location of the path table. The path table pointed to contains // only big-endian values. LocPathTableBE int32 // LBA location of the optional path table. The path table pointed to contains // only big-endian values. Zero means that no optional path table exists. LocOptPathTableBE int32 // contains filtered or unexported fields }
PrimaryVolumePart1 represents the Primary Volume Descriptor first half, before the root directory record. We are only reading big-endian values so placeholders are used for little-endian ones.
type PrimaryVolumePart2 ¶
type PrimaryVolumePart2 struct { // Identifier of the volume set of which this volume is a member. VolumeSetID [128]byte // The volume publisher. For extended publisher information, the first byte // should be 0x5F, followed by the filename of a file in the root directory. // If not specified, all bytes should be 0x20. PublisherID [128]byte // The identifier of the person(s) who prepared the data for this volume. // For extended preparation information, the first byte should be 0x5F, // followed by the filename of a file in the root directory. If not specified, // all bytes should be 0x20. DataPreparerID [128]byte // Identifies how the data are recorded on this volume. For extended information, // the first byte should be 0x5F, followed by the filename of a file in the root // directory. If not specified, all bytes should be 0x20. AppID [128]byte // Filename of a file in the root directory that contains copyright // information for this volume set. If not specified, all bytes should be 0x20. CopyrightFileID [37]byte // Filename of a file in the root directory that contains abstract information // for this volume set. If not specified, all bytes should be 0x20. AbstractFileID [37]byte // Filename of a file in the root directory that contains bibliographic // information for this volume set. If not specified, all bytes should be 0x20. BibliographicFileID [37]byte // The date and time of when the volume was created. CreationTime [17]byte // The date and time of when the volume was modified. ModificationTime [17]byte // The date and time after which this volume is considered to be obsolete. // If not specified, then the volume is never considered to be obsolete. ExpirationTime [17]byte // The date and time after which the volume may be used. If not specified, // the volume may be used immediately. EffectiveTime [17]byte // The directory records and path table version (always 0x01). FileStructVersion byte // Contents not defined by ISO 9660. AppUse [512]byte // contains filtered or unexported fields }
PrimaryVolumePart2 represents the Primary Volume Descriptor half after the root directory record.
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader defines the state of the ISO9660 image reader. It needs to be instantiated from its constructor.
Example ¶
file, err := os.Open("archlinux.iso") if err != nil { panic(err) } r, err := NewReader(file) if err != nil { panic(err) } destPath := "tmp" for { f, err := r.Next() if err == io.EOF { break } if err != nil { panic(err) } fp := filepath.Join(destPath, f.Name()) if f.IsDir() { if err := os.MkdirAll(fp, f.Mode()); err != nil { panic(err) } continue } parentDir, _ := filepath.Split(fp) if err := os.MkdirAll(parentDir, f.Mode()); err != nil { panic(err) } freader := f.Sys().(io.Reader) ff, err := os.Create(fp) if err != nil { panic(err) } defer func() { if err := ff.Close(); err != nil { panic(err) } }() if err := ff.Chmod(f.Mode()); err != nil { panic(err) } if _, err := io.Copy(ff, freader); err != nil { panic(err) } }
Output:
func NewReader ¶
func NewReader(rs io.ReadSeeker) (*Reader, error)
NewReader creates a new ISO 9660 image reader.
type SupplementaryVolume ¶
type SupplementaryVolume struct { VolumeDescriptor Flags int `struc:"int8"` SystemID string `struc:"[32]byte"` ID string `struc:"[32]byte"` Unused byte VolumeSpaceSize int `struc:"int32"` EscapeSequences string `struc:"[32]byte"` VolumeSetSize int `struc:"int16"` VolumeSeqNumber int `struc:"int16"` LogicalBlkSize int `struc:"int16"` PathTableSize int `struc:"int32"` LocLPathTable int `struc:"int32"` LocOptLPathTable int `struc:"int32"` LocMPathTable int `struc:"int32"` LocOptMPathTable int `struc:"int32"` RootDirRecord DirectoryRecord VolumeSetID string `struc:"[128]byte"` PublisherID string `struc:"[128]byte"` DataPreparerID string `struc:"[128]byte"` AppID string `struc:"[128]byte"` CopyrightFileID string `struc:"[37]byte"` AbstractFileID string `struc:"[37]byte"` BibliographicFileID string `struc:"[37]byte"` CreationTime Timestamp ModificationTime Timestamp ExpirationTime Timestamp EffectiveTime Timestamp FileStructVersion int `struc:"int8"` Reserved byte AppData [512]byte Reserved2 byte }
SupplementaryVolume is used by Joliet.
type Terminator ¶
type Terminator struct { VolumeDescriptor // All bytes of this field are set to (00). Reserved [2041]byte }
Terminator indicates the termination of a Volume Descriptor Set.
type Timestamp ¶
type Timestamp struct { Year int `struc:"[4]byte"` Month int `struc:"[2]byte"` DayOfMonth int `struc:"[2]byte"` Hour int `struc:"[2]byte"` Minute int `struc:"[2]byte"` Second int `struc:"[2]byte"` Millisecond int `struc:"[2]byte"` GMTOffset int `struc:"uint8"` }
Timestamp ...
type VolumeDescriptor ¶
type VolumeDescriptor struct { // 0: BootRecord // 1: Primary Volume Descriptor // 2: Supplementary Volume Descriptor // 3: Volume Partition Descriptor // 4-254: Reserved // 255: Volume Descriptor Set Terminator Type byte // Always "CD001". StandardID [5]byte //Volume Descriptor Version (0x01). Version byte }
VolumeDescriptor identify the volume, the partitions recorded on the volume, the volume creator(s), certain attributes of the volume, the location of other recorded descriptors and the version of the standard which applies to the volume descriptor.
When preparing to mount a CD, your first action will be reading the volume descriptors (specifically, you will be looking for the Primary Volume Descriptor). Since sectors 0x00-0x0F of the CD are reserved as System Area, the Volume Descriptors can be found starting at sector 0x10.