arr-pm 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.

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: