arr-pm 0.0.5 → 0.0.6

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.

Files changed (4) hide show
  1. data/arr-pm.gemspec +1 -1
  2. data/lib/arr-pm.rb +0 -63
  3. data/lib/arr-pm/file.rb +66 -23
  4. metadata +1 -1
@@ -2,7 +2,7 @@ Gem::Specification.new do |spec|
2
2
  files = %x{git ls-files}.split("\n")
3
3
 
4
4
  spec.name = "arr-pm"
5
- spec.version = "0.0.5"
5
+ spec.version = "0.0.6"
6
6
  spec.summary = "RPM reader and writer library"
7
7
  spec.description = "This library allows to you to read and write rpm " \
8
8
  "packages. Written in pure ruby because librpm is not available " \
@@ -1,65 +1,2 @@
1
1
  require "arr-pm/namespace"
2
2
  require "arr-pm/file"
3
-
4
- # This class is not yet complete, it is in prototype.
5
- #
6
- # Please use {RPM::File} instead
7
- class RPM
8
- private
9
-
10
- def initialize
11
- #@requires = []
12
- #@conflicts = []
13
- #@provides = []
14
- #@files = []
15
- #@scripts = {}
16
- end
17
-
18
- def requires(name, operator=nil, version=nil)
19
- @requires << [name, operator, version]
20
- end # def requires
21
-
22
- def conflicts(name, operator=nil, version=nil)
23
- @conflicts << [name, operator, version]
24
- end
25
-
26
- def provides(name)
27
- @provides << name
28
- end
29
-
30
- def self.read(path_or_io)
31
- rpmfile = RPM::File.new(path_or_io)
32
- signature = rpmfile.signature
33
- header = rpmfile.header
34
-
35
- header.tags.each do |tag|
36
- p tag
37
- end
38
-
39
- # Things we care about in the header:
40
- # * name, version, release, epoch, summary, description
41
- # *
42
- # * requires, provides, conflicts
43
- # * scripts
44
- # * payload format
45
-
46
- #payload = rpmfile.payload
47
- # Parse the payload, check the rpmfile.header to find tags describing the
48
- # format of the payload.
49
- # Initial target should be gzipped cpio.
50
- end # def self.read
51
-
52
- def files
53
- return @files
54
- end
55
-
56
- # Write this RPM to an IO-like object (must respond to 'write')
57
- def write(io)
58
- # write the lead
59
- # write the signature?
60
- # write the header
61
- # write the payload
62
- end
63
-
64
- public(:files, :requires, :conflicts, :provides, :write)
65
- end # class RPM
@@ -14,6 +14,9 @@ class RPM::File
14
14
  FLAG_GREATER = (1 << 2) # RPMSENSE_GREATER = (1 << 2),
15
15
  FLAG_EQUAL = (1 << 3) # RPMSENSE_EQUAL = (1 << 3),
16
16
 
17
+ # from rpm/rpmfi.h
18
+ FLAG_CONFIG_FILE = (1 << 0) # RPMFILE_CONFIG = (1 << 0)
19
+
17
20
  def initialize(file)
18
21
  if file.is_a?(String)
19
22
  file = File.new(file, "r")
@@ -78,9 +81,9 @@ class RPM::File
78
81
  @payload = @file.clone
79
82
  # The payload starts after the lead, signature, and header. Remember the signature has an
80
83
  # 8-byte boundary-rounding.
81
- @payload.seek(@lead.length + @signature.length + @signature.length % 8 + @header.length, IO::SEEK_SET)
82
84
  end
83
85
 
86
+ @payload.seek(@lead.length + @signature.length + @signature.length % 8 + @header.length, IO::SEEK_SET)
84
87
  return @payload
85
88
  end # def payload
86
89
 
@@ -93,25 +96,17 @@ class RPM::File
93
96
  if !File.directory?(target)
94
97
  raise Errno::ENOENT.new(target)
95
98
  end
96
-
97
- tags = {}
98
- header.tags.each do |tag|
99
- tags[tag.tag] = tag.value
100
- end
101
99
 
102
- # Extract to the 'target' path
103
- #tags[:payloadcompressor] # "xz" or "gzip" or ..?
104
- #tags[:payloadformat] # "cpio"
105
-
106
- extractor = IO.popen("#{tags[:payloadcompressor]} -d | (cd #{target}; cpio -i --make-directories)", "w")
100
+ extractor = IO.popen("#{tags[:payloadcompressor]} -d | (cd #{target}; cpio -i --quiet --make-directories)", "w")
107
101
  buffer = ""
108
102
  buffer.force_encoding("BINARY")
109
- payload_fd = payload
103
+ payload_fd = payload.clone
110
104
  loop do
111
- data = payload.read(16384, buffer)
105
+ data = payload_fd.read(16384, buffer)
112
106
  break if data.nil? # eof
113
107
  extractor.write(data)
114
108
  end
109
+ payload_fd.close
115
110
  extractor.close
116
111
  end # def extract
117
112
 
@@ -170,20 +165,68 @@ class RPM::File
170
165
  #
171
166
  # @return Array of [ [name, operator, version], ... ]
172
167
  def provides
173
- return provides(:provides)
168
+ return relation(:provides)
174
169
  end # def provides
175
170
 
176
- def operator(flag)
177
- have = lambda do |mask|
178
- return (flag & mask) == mask
171
+ # Get an array of config files
172
+ def config_files
173
+ # this stuff seems to be in the 'enum rpmfileAttrs_e' from rpm/rpmfi.h
174
+ results = []
175
+ tags[:fileflags].each_with_index do |flag, i|
176
+ # The :fileflags (and other :file... tags) are an array, in order of
177
+ # files in the rpm payload, we want a list of paths of config files.
178
+ results << files[i] if mask?(flag, FLAG_CONFIG_FILE)
179
179
  end
180
+ return results
181
+ end # def config_files
182
+
183
+ # List the files in this RPM.
184
+ #
185
+ # This should have roughly the same effect as:
186
+ #
187
+ # % rpm2cpio blah.rpm | cpio -it
188
+ def files
189
+ return @files unless @files.nil?
180
190
 
181
- return "<=" if have.call(FLAG_LESS | FLAG_EQUAL)
182
- return ">=" if have.call(FLAG_GREATER | FLAG_EQUAL)
183
- return "=" if have.call(FLAG_EQUAL)
184
- return "<" if have.call(FLAG_LESS)
185
- return ">" if have.call(FLAG_GREATER)
191
+ lister = IO.popen("#{tags[:payloadcompressor]} -d | cpio -it --quiet", "r+")
192
+ buffer = ""
193
+ buffer.force_encoding("BINARY")
194
+ payload_fd = payload.clone
195
+ output = ""
196
+ loop do
197
+ data = payload_fd.read(16384, buffer)
198
+ break if data.nil? # listerextractor.write(data)
199
+ lister.write(data)
200
+
201
+ # Read output from the pipe.
202
+ begin
203
+ output << lister.read_nonblock(16384)
204
+ rescue Errno::EAGAIN
205
+ # do nothing
206
+ end
207
+ end
208
+ lister.close_write
209
+ # Read remaining output
210
+ output << lister.read
211
+ # Split output by newline and strip leading "."
212
+ @files = output.split("\n").collect { |s| s.gsub(/^\./, "") }
213
+ return @files
214
+ ensure
215
+ lister.close unless lister.nil?
216
+ payload_fd.close unless payload_fd.nil?
217
+ end # def files
218
+
219
+ def mask?(value, mask)
220
+ return (value & mask) == mask
221
+ end # def mask?
222
+
223
+ def operator(flag)
224
+ return "<=" if mask?(flag, FLAG_LESS | FLAG_EQUAL)
225
+ return ">=" if mask?(flag, FLAG_GREATER | FLAG_EQUAL)
226
+ return "=" if mask?(flag, FLAG_EQUAL)
227
+ return "<" if mask?(flag, FLAG_LESS)
228
+ return ">" if mask?(flag, FLAG_GREATER)
186
229
  end # def operator
187
230
 
188
- public(:extract, :payload, :header, :lead, :signature, :initialize, :requires)
231
+ public(:extract, :payload, :header, :lead, :signature, :initialize, :requires, :conflicts, :provides)
189
232
  end # class RPM::File
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arr-pm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors: