Class: Omnizip::Formats::Rpm::Lead

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/rpm/lead.rb

Overview

RPM lead structure parser

The lead is a 96-byte deprecated header at the start of RPM files. It contains basic package identification but most information is now stored in the main header.

Constant Summary

Constants included from Constants

Constants::FILE_CONFIG, Constants::FILE_DOC, Constants::FILE_LICENSE, Constants::FILE_README, Constants::FLAG_EQUAL, Constants::FLAG_GREATER, Constants::FLAG_LESS, Constants::HEADER_HEADER_SIZE, Constants::HEADER_MAGIC, Constants::HEADER_SIGNED_TYPE, Constants::LEAD_MAGIC, Constants::LEAD_SIZE, Constants::PACKAGE_BINARY, Constants::PACKAGE_SOURCE, Constants::TAG_ENTRY_SIZE, Constants::TYPE_BINARY, Constants::TYPE_CHAR, Constants::TYPE_I18NSTRING, Constants::TYPE_INT16, Constants::TYPE_INT32, Constants::TYPE_INT64, Constants::TYPE_INT8, Constants::TYPE_NULL, Constants::TYPE_STRING, Constants::TYPE_STRING_ARRAY

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(magic:, major_version:, minor_version:, type:, architecture:, name:, os:, signature_type:, length: LEAD_SIZE) ⇒ Lead

Initialize a parsed lead. All attributes are required; use Lead.parse(io) for the typical read path.



43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/omnizip/formats/rpm/lead.rb', line 43

def initialize(magic:, major_version:, minor_version:, type:,
               architecture:, name:, os:, signature_type:,
               length: LEAD_SIZE)
  @magic = magic
  @major_version = major_version
  @minor_version = minor_version
  @type = type
  @architecture = architecture
  @name = name
  @os = os
  @signature_type = signature_type
  @length = length
end

Instance Attribute Details

#architectureInteger (readonly)

Returns Architecture number.

Returns:

  • (Integer)

    Architecture number



27
28
29
# File 'lib/omnizip/formats/rpm/lead.rb', line 27

def architecture
  @architecture
end

#lengthInteger (readonly)

Returns Total length (always 96).

Returns:

  • (Integer)

    Total length (always 96)



39
40
41
# File 'lib/omnizip/formats/rpm/lead.rb', line 39

def length
  @length
end

#magicString (readonly)

Returns 4-byte magic.

Returns:

  • (String)

    4-byte magic



15
16
17
# File 'lib/omnizip/formats/rpm/lead.rb', line 15

def magic
  @magic
end

#major_versionInteger (readonly)

Returns Major version.

Returns:

  • (Integer)

    Major version



18
19
20
# File 'lib/omnizip/formats/rpm/lead.rb', line 18

def major_version
  @major_version
end

#minor_versionInteger (readonly)

Returns Minor version.

Returns:

  • (Integer)

    Minor version



21
22
23
# File 'lib/omnizip/formats/rpm/lead.rb', line 21

def minor_version
  @minor_version
end

#nameString (readonly)

Returns Package name (66 bytes).

Returns:

  • (String)

    Package name (66 bytes)



30
31
32
# File 'lib/omnizip/formats/rpm/lead.rb', line 30

def name
  @name
end

#osInteger (readonly)

Returns OS number.

Returns:

  • (Integer)

    OS number



33
34
35
# File 'lib/omnizip/formats/rpm/lead.rb', line 33

def os
  @os
end

#signature_typeInteger (readonly)

Returns Signature type.

Returns:

  • (Integer)

    Signature type



36
37
38
# File 'lib/omnizip/formats/rpm/lead.rb', line 36

def signature_type
  @signature_type
end

#typeInteger (readonly)

Returns Package type (binary=0, source=1).

Returns:

  • (Integer)

    Package type (binary=0, source=1)



24
25
26
# File 'lib/omnizip/formats/rpm/lead.rb', line 24

def type
  @type
end

Class Method Details

.parse(io) ⇒ Lead

Parse lead from IO

Parameters:

  • io (IO)

    Input stream positioned at lead

Returns:

  • (Lead)

    Parsed lead object

Raises:

  • (ArgumentError)

    If magic is invalid



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/omnizip/formats/rpm/lead.rb', line 62

def self.parse(io)
  data = io.read(LEAD_SIZE)
  raise ArgumentError, "Failed to read RPM lead" unless data
  raise ArgumentError, "Truncated RPM lead" if data.bytesize < LEAD_SIZE

  # Unpack lead structure
  # A4 = 4-byte string (magic)
  # CC = 2 unsigned chars (major, minor)
  # n = big-endian short (type)
  # n = big-endian short (architecture)
  # A66 = 66-byte string (name)
  # n = big-endian short (os)
  # n = big-endian short (signature_type)
  # A16 = 16-byte reserved
  magic, major, minor, type, arch, name, os, sig_type = data.unpack("A4 CC n n A66 n n A16")

  new(
    magic: magic,
    major_version: major,
    minor_version: minor,
    type: type,
    architecture: arch,
    name: name.strip,
    os: os,
    signature_type: sig_type,
  ).tap(&:validate!)
end

Instance Method Details

#binary?Boolean

Check if package is binary

Returns:

  • (Boolean)


112
113
114
# File 'lib/omnizip/formats/rpm/lead.rb', line 112

def binary?
  @type == PACKAGE_BINARY
end

#source?Boolean

Check if package is source

Returns:

  • (Boolean)


119
120
121
# File 'lib/omnizip/formats/rpm/lead.rb', line 119

def source?
  @type == PACKAGE_SOURCE
end

#type_nameSymbol

Get type name

Returns:

  • (Symbol)

    :binary or :source



126
127
128
# File 'lib/omnizip/formats/rpm/lead.rb', line 126

def type_name
  binary? ? :binary : :source
end

#validate!Object

Validate lead structure

Raises:

  • (ArgumentError)

    If validation fails



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/omnizip/formats/rpm/lead.rb', line 93

def validate!
  if @magic.nil? || @magic.bytesize < 4
    raise ArgumentError, "Invalid RPM magic: missing or truncated"
  end

  unless @magic == LEAD_MAGIC
    raise ArgumentError,
          format("Invalid RPM magic: 0x%08x (expected 0x%08x)",
                 @magic.unpack1("N"), LEAD_MAGIC.unpack1("N"))
  end

  unless [PACKAGE_BINARY, PACKAGE_SOURCE].include?(@type)
    raise ArgumentError, "Invalid RPM type: #{@type}"
  end
end