arr-pm 0.0.6 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of arr-pm might be problematic. Click here for more details.

@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "namespace")
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "namespace"))
2
2
  require File.join(File.dirname(__FILE__), "tag")
3
3
  require "cabin"
4
4
 
@@ -12,7 +12,8 @@ class RPM::File::Header
12
12
  attr_accessor :data_length # rpmlib calls this field 'dl' unhelpfully
13
13
 
14
14
  HEADER_SIGNED_TYPE = 5
15
- HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00"
15
+ HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00".force_encoding("BINARY")
16
+
16
17
  # magic + index_count + data_length
17
18
  HEADER_HEADER_LENGTH = HEADER_MAGIC.length + 4 + 4
18
19
  TAG_ENTRY_SIZE = 16 # tag id, type, offset, count == 16 bytes
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "namespace")
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "namespace"))
2
2
  require "cabin"
3
3
 
4
4
  class RPM::File::Lead
@@ -1,4 +1,4 @@
1
- require File.join(File.dirname(__FILE__), "..", "namespace")
1
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "namespace"))
2
2
  require "cabin"
3
3
 
4
4
  class RPM::File::Tag
@@ -1,3 +1,9 @@
1
1
  class RPM
2
2
  class File; end
3
3
  end
4
+
5
+ module ArrPM
6
+ module V2
7
+ class Package; end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ require "arr-pm/namespace"
2
+
3
+ module ArrPM::V2::Architecture
4
+
5
+ NOARCH = 0
6
+ I386 = 1
7
+ ALPHA = 2
8
+ SPARC = 3
9
+ MIPS = 4
10
+ PPC = 5
11
+ M68K = 6
12
+ IP = 7
13
+ RS6000 = 8
14
+ IA64 = 9
15
+ SPARC64 = 10
16
+ MIPSEL = 11
17
+ ARM = 12
18
+ MK68KMINT = 13
19
+ S390 = 14
20
+ S390X = 15
21
+ PPC64 = 16
22
+ SH = 17
23
+ XTENSA = 18
24
+ X86_64 = 19
25
+
26
+ module_function
27
+
28
+ # Is a given rpm architecture value valid?
29
+ def valid?(value)
30
+ return value >= 0 && value <= 19
31
+ end
32
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+
6
+ module ArrPM::V2::Error
7
+ class Base < StandardError; end
8
+
9
+ class InvalidMagicValue < Base
10
+ def initialize(value)
11
+ super("Got invalid magic value '#{value}'. Expected #{ArrPM::V2::Format::MAGIC}.")
12
+ end
13
+ end
14
+
15
+ class InvalidHeaderMagicValue < Base
16
+ def initialize(value)
17
+ super("Got invalid magic value '#{value}'. Expected #{ArrPM::V2::HeaderHeader::MAGIC}.")
18
+ end
19
+ end
20
+
21
+ class EmptyFile < Base; end
22
+ class ShortFile < Base; end
23
+ class InvalidVersion < Base; end
24
+ class InvalidType < Base
25
+ def initialize(value)
26
+ super("Invalid type: #{value.inspect}")
27
+ end
28
+ end
29
+ class InvalidName < Base; end
30
+ class InvalidArchitecture < Base; end
31
+
32
+ end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+
5
+ module ArrPM::V2::Format
6
+ MAGIC = [0x8e, 0xad, 0xe8]
7
+ MAGIC_LENGTH = MAGIC.count
8
+ MAGIC_STRING = MAGIC.pack("C#{MAGIC_LENGTH}")
9
+
10
+ module_function
11
+ def valid_magic?(magic)
12
+ magic = magic.bytes if magic.is_a?(String)
13
+
14
+ magic == MAGIC
15
+ end
16
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/header_header"
6
+ require "arr-pm/v2/tag"
7
+ require "arr-pm/v2/error"
8
+
9
+ class ArrPM::V2::Header
10
+ attr_reader :tags
11
+
12
+ def load(io)
13
+ headerheader = ArrPM::V2::HeaderHeader.new
14
+ headerheader.load(io)
15
+ headerdata = io.read(headerheader.entries * 16)
16
+ tagdata = io.read(headerheader.bytesize)
17
+ parse(headerdata, headerheader.entries, tagdata)
18
+
19
+ # signature headers are padded up to an 8-byte boundar, details here:
20
+ # http://rpm.org/gitweb?p=rpm.git;a=blob;f=lib/signature.c;h=63e59c00f255a538e48cbc8b0cf3b9bd4a4dbd56;hb=HEAD#l204
21
+ # Throw away the pad.
22
+ io.read(tagdata.length % 8)
23
+ end
24
+
25
+ def parse(data, entry_count, tagdata)
26
+ @tags = entry_count.times.collect do |i|
27
+ tag_number, type_number, offset, count = data[i * 16, 16].unpack("NNNN")
28
+
29
+ tag = ArrPM::V2::Tag.new(tag_number, type_number)
30
+ tag.parse(tagdata, offset, count)
31
+ tag
32
+ end
33
+ nil
34
+ end
35
+ end
@@ -0,0 +1,36 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/error"
6
+
7
+ # The header of an rpm has ... a header. Funky naming :)
8
+ class ArrPM::V2::HeaderHeader
9
+ MAGIC = [ 0x8e, 0xad, 0xe8 ]
10
+ MAGIC_LENGTH = MAGIC.count
11
+
12
+ attr_accessor :version, :entries, :bytesize
13
+
14
+ def load(io)
15
+ data = io.read(16)
16
+ parse(data)
17
+ end
18
+
19
+ def parse(data)
20
+ magic, version, reserved, entries, bytesize = data.unpack("a3Ca4NN")
21
+ self.class.validate_magic(magic.bytes)
22
+
23
+ @version = version
24
+ @entries = entries
25
+ @bytesize = bytesize
26
+ nil
27
+ end
28
+
29
+ def dump
30
+ [magic, 1, 0, @entries, @bytesize].pack("a3Ca4NN")
31
+ end
32
+
33
+ def self.validate_magic(value)
34
+ raise ArrPM::V2::Error::InvalidHeaderMagicValue, value if value != MAGIC
35
+ end
36
+ end
@@ -0,0 +1,121 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+ require "arr-pm/v2/format"
5
+ require "arr-pm/v2/error"
6
+
7
+ class ArrPM::V2::Lead
8
+ LENGTH = 96
9
+ MAGIC = [ 0xed, 0xab, 0xee, 0xdb ]
10
+ MAGIC_LENGTH = MAGIC.count
11
+
12
+ SIGNED_TYPE = 5
13
+
14
+ attr_accessor :major, :minor, :type, :architecture, :name, :os, :signature_type, :reserved
15
+
16
+ def validate
17
+ self.class.validate_type(type)
18
+ self.class.validate_architecture(architecture)
19
+ if name.length > 65
20
+ raise ArrPM::V2::Error::InvalidName, "Name is longer than 65 chracters. This is invalid."
21
+ end
22
+ end
23
+
24
+ def dump(io)
25
+ io.write(serialize)
26
+ end
27
+
28
+ def serialize
29
+ validate
30
+ [ *MAGIC, major, minor, type, architecture, name, os, signature_type, *reserved ].pack("C4CCnnZ66nnC16")
31
+ end
32
+
33
+ def load(io)
34
+ data = io.read(LENGTH)
35
+ parse(data)
36
+ end
37
+
38
+ def parse(bytestring)
39
+ raise ArrPM::V2::Error::EmptyFile if bytestring.nil?
40
+ data = bytestring.bytes
41
+
42
+ @magic = self.class.parse_magic(data)
43
+ @major, @minor = self.class.parse_version(data)
44
+ @type = self.class.parse_type(data)
45
+ @architecture = self.class.parse_architecture(data)
46
+ @name = self.class.parse_name(data)
47
+ @os = self.class.parse_os(data)
48
+ @signature_type = self.class.parse_signature_type(data)
49
+ @reserved = self.class.parse_reserved(data)
50
+ self
51
+ end
52
+
53
+ def signature?
54
+ @signature_type == SIGNED_TYPE
55
+ end
56
+
57
+ def self.valid_version?(version)
58
+ version == 1
59
+ end
60
+
61
+ def self.parse_magic(data)
62
+ magic = data[0, MAGIC_LENGTH]
63
+ validate_magic(magic)
64
+ magic
65
+ end
66
+
67
+ def self.validate_magic(magic)
68
+ raise ArrPM::V2::Error::InvalidMagicValue, magic unless magic == MAGIC
69
+ end
70
+
71
+ def self.parse_version(data)
72
+ offset = MAGIC_LENGTH
73
+ major, minor = data[offset, 2]
74
+ return major, minor
75
+ end
76
+
77
+ def self.parse_type(data)
78
+ offset = MAGIC_LENGTH + 2
79
+ type = data[offset, 2].pack("CC").unpack("n").first
80
+ validate_type(type)
81
+ type
82
+ end
83
+
84
+ def self.validate_type(type)
85
+ raise ArrPM::V2::Error::InvalidType, type unless ArrPM::V2::Type.valid?(type)
86
+ end
87
+
88
+ def self.parse_architecture(data)
89
+ offset = MAGIC_LENGTH + 4
90
+ architecture = data[offset, 2].pack("C*").unpack("n").first
91
+ validate_architecture(architecture)
92
+ architecture
93
+ end
94
+
95
+ def self.validate_architecture(architecture)
96
+ raise ArrPM::V2::Error::InvalidArchitecture unless ArrPM::V2::Architecture.valid?(architecture)
97
+ end
98
+
99
+ def self.parse_name(data)
100
+ offset = MAGIC_LENGTH + 6
101
+ name = data[offset, 66]
102
+ length = name.find_index(0) # find the first null byte
103
+ raise ArrPM::V2::Error::InvalidName unless length
104
+ return name[0, length].pack("C*")
105
+ end
106
+
107
+ def self.parse_os(data)
108
+ offset = MAGIC_LENGTH + 72
109
+ data[offset, 2].pack("C*").unpack("n").first
110
+ end
111
+
112
+ def self.parse_signature_type(data)
113
+ offset = MAGIC_LENGTH + 74
114
+ data[offset, 2].pack("C*").unpack("n").first
115
+ end
116
+
117
+ def self.parse_reserved(data)
118
+ offset = MAGIC_LENGTH + 76
119
+ data[offset, 16]
120
+ end
121
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+
3
+ require "arr-pm/namespace"
4
+
5
+ class ArrPM::V2::RPM
6
+ attr_accessor :name
7
+ attr_accessor :epoch
8
+ attr_accessor :version
9
+ attr_accessor :release
10
+
11
+ def initialize
12
+ defaults
13
+ end
14
+
15
+ def defaults
16
+ @type = Type::BINARY
17
+ end
18
+ end
@@ -0,0 +1,295 @@
1
+ require "arr-pm/namespace"
2
+
3
+ class ArrPM::V2::Tag
4
+ module Type
5
+ NULL = 0
6
+ CHAR = 1
7
+ INT8 = 2
8
+ INT16 = 3
9
+ INT32 = 4
10
+ INT64 = 5
11
+ STRING = 6
12
+ BINARY = 7
13
+ STRING_ARRAY = 8
14
+ I18NSTRING = 9
15
+
16
+ TYPE_MAP = Hash[constants.collect { |c| [const_get(c), c] }]
17
+
18
+ def self.parse(data, type, offset, count)
19
+ case type
20
+ when NULL
21
+ nil
22
+ when CHAR
23
+ data[offset, count].unpack("A#{count}")
24
+ when INT8
25
+ data[offset, count].unpack("C" * count)
26
+ when INT16
27
+ data[offset, 2 * count].unpack("n" * count)
28
+ when INT32
29
+ data[offset, 4 * count].unpack("N" * count)
30
+ when INT64
31
+ a, b = data[offset, 8].unpack("NN")
32
+ a << 32 + b
33
+ when STRING, I18NSTRING
34
+ data[offset..-1][/^[^\0]*/]
35
+ when BINARY
36
+ data[offset, count]
37
+ when STRING_ARRAY
38
+ data[offset..-1].split("\0")[0...count]
39
+ else
40
+ raise ArrPM::V2::Error::InvalidType, type
41
+ end
42
+ end
43
+ end # module Type
44
+
45
+ HEADERIMAGE = 61
46
+ HEADERSIGNATURES = 62
47
+ HEADERIMMUTABLE = 63
48
+ HEADERREGIONS = 64
49
+ HEADERI18NTABLE = 100
50
+ SIG_BASE = 256
51
+
52
+ SIGSIZE = 257
53
+ SIGLEMD5_1 = 258
54
+ SIGPGP = 259
55
+ SIGLEMD5_2 = 260
56
+ SIGMD5 = 261
57
+ SIGGPG = 262
58
+ SIGPGP5 = 263
59
+ BADSHA1_1 = 264
60
+ BADSHA1_2 = 265
61
+ PUBKEYS = 266
62
+ DSAHEADER = 267
63
+ RSAHEADER = 268
64
+ SHA1HEADER = 269
65
+ LONGSIGSIZE = 270
66
+ LONGARCHIVESIZE = 271
67
+
68
+ NAME = 1000
69
+ VERSION = 1001
70
+ RELEASE = 1002
71
+ EPOCH = 1003
72
+ SUMMARY = 1004
73
+ DESCRIPTION = 1005
74
+ BUILDTIME = 1006
75
+ BUILDHOST = 1007
76
+ INSTALLTIME = 1008
77
+ SIZE = 1009
78
+ DISTRIBUTION = 1010
79
+ VENDOR = 1011
80
+ GIF = 1012
81
+ XPM = 1013
82
+ LICENSE = 1014
83
+ PACKAGER = 1015
84
+ GROUP = 1016
85
+ CHANGELOG = 1017
86
+ SOURCE = 1018
87
+ PATCH = 1019
88
+ URL = 1020
89
+ OS = 1021
90
+ ARCH = 1022
91
+ PREIN = 1023
92
+ POSTIN = 1024
93
+ PREUN = 1025
94
+ POSTUN = 1026
95
+ OLDFILENAMES = 1027
96
+ FILESIZES = 1028
97
+ FILESTATES = 1029
98
+ FILEMODES = 1030
99
+ FILEUIDS = 1031
100
+ FILEGIDS = 1032
101
+ FILERDEVS = 1033
102
+ FILEMTIMES = 1034
103
+ FILEDIGESTS = 1035
104
+ FILELINKTOS = 1036
105
+ FILEFLAGS = 1037
106
+ ROOT = 1038
107
+ FILEUSERNAME = 1039
108
+ FILEGROUPNAME = 1040
109
+ EXCLUDE = 1041
110
+ EXCLUSIVE = 1042
111
+ ICON = 1043
112
+ SOURCERPM = 1044
113
+ FILEVERIFYFLAGS = 1045
114
+ ARCHIVESIZE = 1046
115
+ PROVIDENAME = 1047
116
+ REQUIREFLAGS = 1048
117
+ REQUIRENAME = 1049
118
+ REQUIREVERSION = 1050
119
+ NOSOURCE = 1051
120
+ NOPATCH = 1052
121
+ CONFLICTFLAGS = 1053
122
+ CONFLICTNAME = 1054
123
+ CONFLICTVERSION = 1055
124
+ DEFAULTPREFIX = 1056
125
+ BUILDROOT = 1057
126
+ INSTALLPREFIX = 1058
127
+ EXCLUDEARCH = 1059
128
+ EXCLUDEOS = 1060
129
+ EXCLUSIVEARCH = 1061
130
+ EXCLUSIVEOS = 1062
131
+ AUTOREQPROV = 1063
132
+ RPMVERSION = 1064
133
+ TRIGGERSCRIPTS = 1065
134
+ TRIGGERNAME = 1066
135
+ TRIGGERVERSION = 1067
136
+ TRIGGERFLAGS = 1068
137
+ TRIGGERINDEX = 1069
138
+ VERIFYSCRIPT = 1079
139
+ CHANGELOGTIME = 1080
140
+ CHANGELOGNAME = 1081
141
+ CHANGELOGTEXT = 1082
142
+ BROKENMD5 = 1083
143
+ PREREQ = 1084
144
+ PREINPROG = 1085
145
+ POSTINPROG = 1086
146
+ PREUNPROG = 1087
147
+ POSTUNPROG = 1088
148
+ BUILDARCHS = 1089
149
+ OBSOLETENAME = 1090
150
+ VERIFYSCRIPTPROG = 1091
151
+ TRIGGERSCRIPTPROG = 1092
152
+ DOCDIR = 1093
153
+ COOKIE = 1094
154
+ FILEDEVICES = 1095
155
+ FILEINODES = 1096
156
+ FILELANGS = 1097
157
+ PREFIXES = 1098
158
+ INSTPREFIXES = 1099
159
+ TRIGGERIN = 1100
160
+ TRIGGERUN = 1101
161
+ TRIGGERPOSTUN = 1102
162
+ AUTOREQ = 1103
163
+ AUTOPROV = 1104
164
+ CAPABILITY = 1105
165
+ SOURCEPACKAGE = 1106
166
+ OLDORIGFILENAMES = 1107
167
+ BUILDPREREQ = 1108
168
+ BUILDREQUIRES = 1109
169
+ BUILDCONFLICTS = 1110
170
+ BUILDMACROS = 1111
171
+ PROVIDEFLAGS = 1112
172
+ PROVIDEVERSION = 1113
173
+ OBSOLETEFLAGS = 1114
174
+ OBSOLETEVERSION = 1115
175
+ DIRINDEXES = 1116
176
+ BASENAMES = 1117
177
+ DIRNAMES = 1118
178
+ ORIGDIRINDEXES = 1119
179
+ ORIGBASENAMES = 1120
180
+ ORIGDIRNAMES = 1121
181
+ OPTFLAGS = 1122
182
+ DISTURL = 1123
183
+ PAYLOADFORMAT = 1124
184
+ PAYLOADCOMPRESSOR = 1125
185
+ PAYLOADFLAGS = 1126
186
+ INSTALLCOLOR = 1127
187
+ INSTALLTID = 1128
188
+ REMOVETID = 1129
189
+ SHA1RHN = 1130
190
+ RHNPLATFORM = 1131
191
+ PLATFORM = 1132
192
+ PATCHESNAME = 1133
193
+ PATCHESFLAGS = 1134
194
+ PATCHESVERSION = 1135
195
+ CACHECTIME = 1136
196
+ CACHEPKGPATH = 1137
197
+ CACHEPKGSIZE = 1138
198
+ CACHEPKGMTIME = 1139
199
+ FILECOLORS = 1140
200
+ FILECLASS = 1141
201
+ CLASSDICT = 1142
202
+ FILEDEPENDSX = 1143
203
+ FILEDEPENDSN = 1144
204
+ DEPENDSDICT = 1145
205
+ SOURCEPKGID = 1146
206
+ FILECONTEXTS = 1147
207
+ FSCONTEXTS = 1148
208
+ RECONTEXTS = 1149
209
+ POLICIES = 1150
210
+ PRETRANS = 1151
211
+ POSTTRANS = 1152
212
+ PRETRANSPROG = 1153
213
+ POSTTRANSPROG = 1154
214
+ DISTTAG = 1155
215
+ SUGGESTSNAME = 1156
216
+ SUGGESTSVERSION = 1157
217
+ SUGGESTSFLAGS = 1158
218
+ ENHANCESNAME = 1159
219
+ ENHANCESVERSION = 1160
220
+ ENHANCESFLAGS = 1161
221
+ PRIORITY = 1162
222
+ CVSID = 1163
223
+ BLINKPKGID = 1164
224
+ BLINKHDRID = 1165
225
+ BLINKNEVRA = 1166
226
+ FLINKPKGID = 1167
227
+ FLINKHDRID = 1168
228
+ FLINKNEVRA = 1169
229
+ PACKAGEORIGIN = 1170
230
+ TRIGGERPREIN = 1171
231
+ BUILDSUGGESTS = 1172
232
+ BUILDENHANCES = 1173
233
+ SCRIPTSTATES = 1174
234
+ SCRIPTMETRICS = 1175
235
+ BUILDCPUCLOCK = 1176
236
+ FILEDIGESTALGOS = 1177
237
+ VARIANTS = 1178
238
+ XMAJOR = 1179
239
+ XMINOR = 1180
240
+ REPOTAG = 1181
241
+ KEYWORDS = 1182
242
+ BUILDPLATFORMS = 1183
243
+ PACKAGECOLOR = 1184
244
+ PACKAGEPREFCOLOR = 1185
245
+ XATTRSDICT = 1186
246
+ FILEXATTRSX = 1187
247
+ DEPATTRSDICT = 1188
248
+ CONFLICTATTRSX = 1189
249
+ OBSOLETEATTRSX = 1190
250
+ PROVIDEATTRSX = 1191
251
+ REQUIREATTRSX = 1192
252
+ BUILDPROVIDES = 1193
253
+ BUILDOBSOLETES = 1194
254
+ DBINSTANCE = 1195
255
+ NVRA = 1196
256
+ FILENAMES = 5000
257
+ FILEPROVIDE = 5001
258
+ FILEREQUIRE = 5002
259
+ FSNAMES = 5003
260
+ FSSIZES = 5004
261
+ TRIGGERCONDS = 5005
262
+ TRIGGERTYPE = 5006
263
+ ORIGFILENAMES = 5007
264
+ LONGFILESIZES = 5008
265
+ LONGSIZE = 5009
266
+ FILECAPS = 5010
267
+ FILEDIGESTALGO = 5011
268
+ BUGURL = 5012
269
+ EVR = 5013
270
+ NVR = 5014
271
+ NEVR = 5015
272
+ NEVRA = 5016
273
+ HEADERCOLOR = 5017
274
+ VERBOSE = 5018
275
+ EPOCHNUM = 5019
276
+ ENCODING = 5062
277
+
278
+ TAG_MAP = Hash[constants.collect { |c| [const_get(c), c] }]
279
+
280
+ attr_accessor :tag, :type, :value
281
+
282
+ def initialize(tag_number, type_number)
283
+ @tag = self.class::TAG_MAP[tag_number] || tag_number
284
+ @type = type_number
285
+ end
286
+
287
+ def parse(data, offset, count)
288
+ @value = Type.parse(data, @type, offset, count)
289
+ nil
290
+ end
291
+
292
+ def inspect
293
+ format("<%s#%s> %s/%d value=%s>", self.class.name, self.object_id, @tag, @type, @value.inspect)
294
+ end
295
+ end # module ArrPM::V2::Tag