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.
- checksums.yaml +7 -0
- data/.rubocop.yml +73 -0
- data/Gemfile +3 -1
- data/Guardfile +77 -0
- data/Makefile +0 -19
- data/arr-pm.gemspec +3 -1
- data/cpio.rb +202 -0
- data/lib/arr-pm/file.rb +34 -10
- data/lib/arr-pm/file/header.rb +3 -2
- data/lib/arr-pm/file/lead.rb +1 -1
- data/lib/arr-pm/file/tag.rb +1 -1
- data/lib/arr-pm/namespace.rb +6 -0
- data/lib/arr-pm/v2/architecture.rb +32 -0
- data/lib/arr-pm/v2/error.rb +32 -0
- data/lib/arr-pm/v2/format.rb +16 -0
- data/lib/arr-pm/v2/header.rb +35 -0
- data/lib/arr-pm/v2/header_header.rb +36 -0
- data/lib/arr-pm/v2/lead.rb +121 -0
- data/lib/arr-pm/v2/package.rb +18 -0
- data/lib/arr-pm/v2/tag.rb +295 -0
- data/lib/arr-pm/v2/type.rb +15 -0
- data/spec/arr-pm/v2/header_spec.rb +34 -0
- data/spec/arr-pm/v2/lead_spec.rb +125 -0
- data/spec/fixtures/example-1.0-1.x86_64.rpm +0 -0
- data/spec/fixtures/example.json +55 -0
- metadata +45 -27
- data/header-verify.rb +0 -71
- data/notify-failure.sh +0 -15
- data/printrpm.rb +0 -22
- data/test/all.rb +0 -24
- data/test/docs.rb +0 -42
- data/test/testing.rb +0 -14
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ceb08ab00b24c659ee4f0fd42d8f5c8ad77416ffff3f89e8ee18ec46ddc58383
|
4
|
+
data.tar.gz: b53d4d64c24362fb2cf27606842d8352e9f7d184f9ba3b76eb1e33b3e13b2775
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 441b7c7a0d0851c3c4cadaf7e2e0f20d32388ba4df722ee3f76bfb3a34bb072739daf63739cf19e9d8f221a40a80f999ca47b2825043ded493d1f3363dec3e54
|
7
|
+
data.tar.gz: 815d8fff66bc8672b7e212f6c138795a9029b5e78032d26051ac114e306084f97d01519060427aeb50e9bca29dd49af5d5567370904d8881fc99179184811cd3
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
# Let's not argue over this...
|
2
|
+
StringLiterals:
|
3
|
+
Enabled: false
|
4
|
+
|
5
|
+
# I can't find a reason for raise vs fail.
|
6
|
+
SignalException:
|
7
|
+
Enabled: false
|
8
|
+
|
9
|
+
# I can't find a reason to prefer 'map' when 'collect' is what I mean.
|
10
|
+
# I'm collecting things from a list. Maybe someone can help me understand the
|
11
|
+
# semantics here.
|
12
|
+
CollectionMethods:
|
13
|
+
Enabled: false
|
14
|
+
|
15
|
+
# Why do you even *SEE* trailing whitespace? Because your editor was
|
16
|
+
# misconfigured to highlight trailing whitespace, right? Maybe turn that off?
|
17
|
+
# ;)
|
18
|
+
TrailingWhitespace:
|
19
|
+
Enabled: false
|
20
|
+
|
21
|
+
# Line length is another weird problem that somehow in the past 40 years of
|
22
|
+
# computing we don't seem to have solved. It's a display problem :(
|
23
|
+
LineLength:
|
24
|
+
Max: 9000
|
25
|
+
|
26
|
+
# %w() vs [ "x", "y", ... ]
|
27
|
+
# The complaint is on lib/pleaserun/detector.rb's map of OS=>Runner,
|
28
|
+
# i'll ignore it.
|
29
|
+
WordArray:
|
30
|
+
MinSize: 5
|
31
|
+
|
32
|
+
# A 20-line method isn't too bad.
|
33
|
+
MethodLength:
|
34
|
+
Max: 20
|
35
|
+
|
36
|
+
# Hash rockets (=>) forever. Why? Not all of my hash keys are static symbols.
|
37
|
+
HashSyntax:
|
38
|
+
EnforcedStyle: hash_rockets
|
39
|
+
|
40
|
+
# I prefer explicit return. It makes it clear in the code that the
|
41
|
+
# code author intended to return a value from a method.
|
42
|
+
RedundantReturn:
|
43
|
+
Enabled: false
|
44
|
+
|
45
|
+
# My view on a readable case statement seems to disagree with
|
46
|
+
# what rubocop wants and it doesn't let me configure it other than
|
47
|
+
# enable/disable.
|
48
|
+
CaseIndentation:
|
49
|
+
Enabled: false
|
50
|
+
|
51
|
+
# module This::Module::Definition is good.
|
52
|
+
Style/ClassAndModuleChildren:
|
53
|
+
Enabled: true
|
54
|
+
EnforcedStyle: compact
|
55
|
+
|
56
|
+
# "in interpolation #{use.some("double quotes is ok")}"
|
57
|
+
Style/StringLiteralsInInterpolation:
|
58
|
+
Enabled: true
|
59
|
+
EnforcedStyle: double_quotes
|
60
|
+
|
61
|
+
# Long-block `if !something ... end` are more readable to me than `unless something ... end`
|
62
|
+
Style/NegatedIf:
|
63
|
+
Enabled: false
|
64
|
+
|
65
|
+
Style/NumericLiterals:
|
66
|
+
MinDigits: 6
|
67
|
+
|
68
|
+
# This kind of style "useless use of %x" assumes code is write-once.
|
69
|
+
Style/UnneededPercentX:
|
70
|
+
Enabled: false
|
71
|
+
|
72
|
+
Style/FileName:
|
73
|
+
Enabled: false
|
data/Gemfile
CHANGED
data/Guardfile
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec features)
|
6
|
+
|
7
|
+
## Uncomment to clear the screen before every task
|
8
|
+
# clearing :on
|
9
|
+
|
10
|
+
## Guard internally checks for changes in the Guardfile and exits.
|
11
|
+
## If you want Guard to automatically start up again, run guard in a
|
12
|
+
## shell loop, e.g.:
|
13
|
+
##
|
14
|
+
## $ while bundle exec guard; do echo "Restarting Guard..."; done
|
15
|
+
##
|
16
|
+
## Note: if you are using the `directories` clause above and you are not
|
17
|
+
## watching the project directory ('.'), then you will want to move
|
18
|
+
## the Guardfile to a watched dir and symlink it back, e.g.
|
19
|
+
#
|
20
|
+
# $ mkdir config
|
21
|
+
# $ mv Guardfile config/
|
22
|
+
# $ ln -s config/Guardfile .
|
23
|
+
#
|
24
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
25
|
+
|
26
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
27
|
+
# rspec may be run, below are examples of the most common uses.
|
28
|
+
# * bundler: 'bundle exec rspec'
|
29
|
+
# * bundler binstubs: 'bin/rspec'
|
30
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
31
|
+
# installed the spring binstubs per the docs)
|
32
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
33
|
+
# * 'just' rspec: 'rspec'
|
34
|
+
|
35
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
36
|
+
require "guard/rspec/dsl"
|
37
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
38
|
+
|
39
|
+
# Feel free to open issues for suggestions and improvements
|
40
|
+
|
41
|
+
# RSpec files
|
42
|
+
rspec = dsl.rspec
|
43
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
44
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
45
|
+
watch(rspec.spec_files)
|
46
|
+
|
47
|
+
# Ruby files
|
48
|
+
ruby = dsl.ruby
|
49
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
50
|
+
|
51
|
+
# Rails files
|
52
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
53
|
+
dsl.watch_spec_files_for(rails.app_files)
|
54
|
+
dsl.watch_spec_files_for(rails.views)
|
55
|
+
|
56
|
+
watch(rails.controllers) do |m|
|
57
|
+
[
|
58
|
+
rspec.spec.("routing/#{m[1]}_routing"),
|
59
|
+
rspec.spec.("controllers/#{m[1]}_controller"),
|
60
|
+
rspec.spec.("acceptance/#{m[1]}")
|
61
|
+
]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Rails config changes
|
65
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
66
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
67
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
68
|
+
|
69
|
+
# Capybara features specs
|
70
|
+
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
71
|
+
|
72
|
+
# Turnip features and steps
|
73
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
74
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
75
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
76
|
+
end
|
77
|
+
end
|
data/Makefile
CHANGED
@@ -3,25 +3,6 @@ VERSION=$(shell awk -F\" '/spec.version/ { print $$2 }' $(GEMSPEC))
|
|
3
3
|
NAME=$(shell awk -F\" '/spec.name/ { print $$2 }' $(GEMSPEC))
|
4
4
|
GEM=$(NAME)-$(VERSION).gem
|
5
5
|
|
6
|
-
.PHONY: test
|
7
|
-
test:
|
8
|
-
sh notify-failure.sh ruby test/all.rb
|
9
|
-
|
10
|
-
.PHONY: testloop
|
11
|
-
testloop:
|
12
|
-
while true; do \
|
13
|
-
$(MAKE) test; \
|
14
|
-
$(MAKE) wait-for-changes; \
|
15
|
-
done
|
16
|
-
|
17
|
-
.PHONY: serve-coverage
|
18
|
-
serve-coverage:
|
19
|
-
cd coverage; python -mSimpleHTTPServer
|
20
|
-
|
21
|
-
.PHONY: wait-for-changes
|
22
|
-
wait-for-changes:
|
23
|
-
-inotifywait --exclude '\.swp' -e modify $$(find $(DIRS) -name '*.rb'; find $(DIRS) -type d)
|
24
|
-
|
25
6
|
.PHONY: package
|
26
7
|
package: | $(GEM)
|
27
8
|
|
data/arr-pm.gemspec
CHANGED
@@ -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
|
+
spec.version = "0.0.11"
|
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 " \
|
@@ -16,6 +16,8 @@ Gem::Specification.new do |spec|
|
|
16
16
|
|
17
17
|
spec.authors = ["Jordan Sissel"]
|
18
18
|
spec.email = ["jls@semicomplete.com"]
|
19
|
+
|
20
|
+
spec.add_development_dependency "flores", ">0"
|
19
21
|
#spec.homepage = "..."
|
20
22
|
end
|
21
23
|
|
data/cpio.rb
ADDED
@@ -0,0 +1,202 @@
|
|
1
|
+
class BoundedIO
|
2
|
+
attr_reader :length
|
3
|
+
attr_reader :remaining
|
4
|
+
|
5
|
+
def initialize(io, length, &eof_callback)
|
6
|
+
@io = io
|
7
|
+
@length = length
|
8
|
+
@remaining = length
|
9
|
+
|
10
|
+
@eof_callback = eof_callback
|
11
|
+
@eof = false
|
12
|
+
end
|
13
|
+
|
14
|
+
def read(size=nil)
|
15
|
+
return nil if eof?
|
16
|
+
size = @remaining if size.nil?
|
17
|
+
data = @io.read(size)
|
18
|
+
@remaining -= data.bytesize
|
19
|
+
eof?
|
20
|
+
data
|
21
|
+
end
|
22
|
+
|
23
|
+
def sysread(size)
|
24
|
+
raise EOFError, "end of file reached" if eof?
|
25
|
+
read(size)
|
26
|
+
end
|
27
|
+
|
28
|
+
def eof?
|
29
|
+
return false if @remaining > 0
|
30
|
+
return @eof if @eof
|
31
|
+
|
32
|
+
@eof_callback.call
|
33
|
+
@eof = true
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
module CPIO
|
38
|
+
FIELDS = [
|
39
|
+
:magic, :ino, :mode, :uid, :gid, :nlink, :mtime, :filesize, :devmajor,
|
40
|
+
:devminor, :rdevmajor, :rdevminor, :namesize, :check
|
41
|
+
]
|
42
|
+
end
|
43
|
+
|
44
|
+
class CPIO::ASCIIReader
|
45
|
+
FIELD_SIZES = {
|
46
|
+
:magic => 6,
|
47
|
+
:ino => 8,
|
48
|
+
:mode => 8,
|
49
|
+
:uid => 8,
|
50
|
+
:gid => 8,
|
51
|
+
:nlink => 8,
|
52
|
+
:mtime => 8,
|
53
|
+
:filesize => 8,
|
54
|
+
:devmajor => 8,
|
55
|
+
:devminor => 8,
|
56
|
+
:rdevmajor => 8,
|
57
|
+
:rdevminor => 8,
|
58
|
+
:namesize => 8,
|
59
|
+
:check => 8
|
60
|
+
}
|
61
|
+
HEADER_LENGTH = FIELD_SIZES.reduce(0) { |m, (_, v)| m + v }
|
62
|
+
HEADER_PACK = FIELD_SIZES.collect { |_, v| "A#{v}" }.join
|
63
|
+
|
64
|
+
FIELD_ORDER = [
|
65
|
+
:magic, :ino, :mode, :uid, :gid, :nlink, :mtime, :filesize, :devmajor,
|
66
|
+
:devminor, :rdevmajor, :rdevminor, :namesize, :check
|
67
|
+
]
|
68
|
+
|
69
|
+
def initialize(io)
|
70
|
+
@io = io
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def io
|
76
|
+
@io
|
77
|
+
end
|
78
|
+
|
79
|
+
def each(&block)
|
80
|
+
while true
|
81
|
+
entry = read
|
82
|
+
break if entry.nil?
|
83
|
+
# The CPIO format has the end-of-stream marker as a file called "TRAILER!!!"
|
84
|
+
break if entry.name == "TRAILER!!!"
|
85
|
+
block.call(entry, entry.file)
|
86
|
+
verify_correct_read(entry) unless entry.directory?
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def verify_correct_read(entry)
|
91
|
+
# Read and throw away the whole file if not read at all.
|
92
|
+
entry.file.tap do |file|
|
93
|
+
if file.nil? || file.remaining == 0
|
94
|
+
# All OK! :)
|
95
|
+
elsif file.remaining == file.length
|
96
|
+
file.read(16384) while !file.eof?
|
97
|
+
else
|
98
|
+
# The file was only partially read? This should be an error by the
|
99
|
+
# user.
|
100
|
+
consumed = file.length - file.remaining
|
101
|
+
raise BadState, "Only #{consumed} bytes were read of the #{file.length} byte file: #{entry.name}"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def read
|
107
|
+
entry = CPIOEntry.new
|
108
|
+
header = io.read(HEADER_LENGTH)
|
109
|
+
return nil if header.nil?
|
110
|
+
FIELD_ORDER.zip(header.unpack(HEADER_PACK)).each do |field, value|
|
111
|
+
entry.send("#{field}=", value.to_i(16))
|
112
|
+
end
|
113
|
+
|
114
|
+
entry.validate
|
115
|
+
entry.mtime = Time.at(entry.mtime)
|
116
|
+
read_name(entry, @io)
|
117
|
+
read_file(entry, @io)
|
118
|
+
entry
|
119
|
+
end
|
120
|
+
|
121
|
+
def read_name(entry, io)
|
122
|
+
entry.name = io.read(entry.namesize - 1) # - 1 for null terminator
|
123
|
+
nul = io.read(1)
|
124
|
+
raise ArgumentError, "Corrupt CPIO or bug? Name null terminator was not null: #{nul.inspect}" if nul != "\0"
|
125
|
+
padding_data = io.read(padding_name(entry))
|
126
|
+
# Padding should be all null bytes
|
127
|
+
if padding_data != ("\0" * padding_data.bytesize)
|
128
|
+
raise ArgumentError, "Corrupt CPIO or bug? Name null padding was #{padding_name(entry)} bytes: #{padding_data.inspect}"
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def read_file(entry, io)
|
133
|
+
if entry.directory?
|
134
|
+
entry.file = nil
|
135
|
+
#read_file_padding(entry, io)
|
136
|
+
nil
|
137
|
+
else
|
138
|
+
entry.file = BoundedIO.new(io, entry.filesize) do
|
139
|
+
read_file_padding(entry, io)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def read_file_padding(entry, io)
|
145
|
+
padding_data = io.read(padding_file(entry))
|
146
|
+
if padding_data != ("\0" * padding_data.bytesize)
|
147
|
+
raise ArgumentError, "Corrupt CPIO or bug? File null padding was #{padding_file(entry)} bytes: #{padding_data.inspect}"
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def padding_name(entry)
|
152
|
+
# name padding is padding up to a multiple of 4 after header+namesize
|
153
|
+
-(HEADER_LENGTH + entry.namesize) % 4
|
154
|
+
end
|
155
|
+
|
156
|
+
def padding_file(entry)
|
157
|
+
(-(HEADER_LENGTH + entry.filesize + 2) % 4)
|
158
|
+
end
|
159
|
+
public(:each)
|
160
|
+
end
|
161
|
+
|
162
|
+
class CPIOEntry
|
163
|
+
CPIO::FIELDS.each do |field|
|
164
|
+
attr_accessor field
|
165
|
+
end
|
166
|
+
|
167
|
+
attr_accessor :name
|
168
|
+
attr_accessor :file
|
169
|
+
|
170
|
+
DIRECTORY_FLAG = 0040000
|
171
|
+
|
172
|
+
def validate
|
173
|
+
raise "Invalid magic #{magic.inspect}" if magic != 0x070701
|
174
|
+
raise "Invalid ino #{ino.inspect}" if ino < 0
|
175
|
+
raise "Invalid mode #{mode.inspect}" if mode < 0
|
176
|
+
raise "Invalid uid #{uid.inspect}" if uid < 0
|
177
|
+
raise "Invalid gid #{gid.inspect}" if gid < 0
|
178
|
+
raise "Invalid nlink #{nlink.inspect}" if nlink < 0
|
179
|
+
raise "Invalid mtime #{mtime.inspect}" if mtime < 0
|
180
|
+
raise "Invalid filesize #{filesize.inspect}" if filesize < 0
|
181
|
+
raise "Invalid devmajor #{devmajor.inspect}" if devmajor < 0
|
182
|
+
raise "Invalid devminor #{devminor.inspect}" if devminor < 0
|
183
|
+
raise "Invalid rdevmajor #{rdevmajor.inspect}" if rdevmajor < 0
|
184
|
+
raise "Invalid rdevminor #{rdevminor.inspect}" if rdevminor < 0
|
185
|
+
raise "Invalid namesize #{namesize.inspect}" if namesize < 0
|
186
|
+
raise "Invalid check #{check.inspect}" if check < 0
|
187
|
+
end # def validate
|
188
|
+
|
189
|
+
def read(*args)
|
190
|
+
return nil if directory?
|
191
|
+
file.read(*args)
|
192
|
+
end
|
193
|
+
|
194
|
+
def directory?
|
195
|
+
mode & DIRECTORY_FLAG > 0
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
CPIO::ASCIIReader.new(STDIN).each do |entry, file|
|
200
|
+
puts entry.name
|
201
|
+
file.read unless entry.directory?
|
202
|
+
end
|
data/lib/arr-pm/file.rb
CHANGED
@@ -2,6 +2,7 @@ require File.join(File.dirname(__FILE__), "namespace")
|
|
2
2
|
require File.join(File.dirname(__FILE__), "file", "header")
|
3
3
|
require File.join(File.dirname(__FILE__), "file", "lead")
|
4
4
|
require File.join(File.dirname(__FILE__), "file", "tag")
|
5
|
+
require "fcntl"
|
5
6
|
|
6
7
|
# Much of the code here is derived from knowledge gained by reading the rpm
|
7
8
|
# source code, but mostly it started making more sense after reading this site:
|
@@ -99,7 +100,11 @@ class RPM::File
|
|
99
100
|
|
100
101
|
extractor = IO.popen("#{tags[:payloadcompressor]} -d | (cd #{target}; cpio -i --quiet --make-directories)", "w")
|
101
102
|
buffer = ""
|
102
|
-
|
103
|
+
begin
|
104
|
+
buffer.force_encoding("BINARY")
|
105
|
+
rescue NoMethodError
|
106
|
+
# Do Nothing
|
107
|
+
end
|
103
108
|
payload_fd = payload.clone
|
104
109
|
loop do
|
105
110
|
data = payload_fd.read(16384, buffer)
|
@@ -158,24 +163,28 @@ class RPM::File
|
|
158
163
|
#
|
159
164
|
# @return Array of [ [name, operator, version], ... ]
|
160
165
|
def conflicts
|
161
|
-
return relation(:
|
166
|
+
return relation(:conflict)
|
162
167
|
end # def conflicts
|
163
168
|
|
164
169
|
# Get an array of provides defined in this package.
|
165
170
|
#
|
166
171
|
# @return Array of [ [name, operator, version], ... ]
|
167
172
|
def provides
|
168
|
-
return relation(:
|
173
|
+
return relation(:provide)
|
169
174
|
end # def provides
|
170
175
|
|
171
176
|
# Get an array of config files
|
172
177
|
def config_files
|
173
178
|
# this stuff seems to be in the 'enum rpmfileAttrs_e' from rpm/rpmfi.h
|
174
179
|
results = []
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
180
|
+
# short-circuit if there's no :fileflags tag
|
181
|
+
return results unless tags.include?(:fileflags)
|
182
|
+
if !tags[:fileflags].nil?
|
183
|
+
tags[:fileflags].each_with_index do |flag, i|
|
184
|
+
# The :fileflags (and other :file... tags) are an array, in order of
|
185
|
+
# files in the rpm payload, we want a list of paths of config files.
|
186
|
+
results << files[i] if mask?(flag, FLAG_CONFIG_FILE)
|
187
|
+
end
|
179
188
|
end
|
180
189
|
return results
|
181
190
|
end # def config_files
|
@@ -190,7 +199,11 @@ class RPM::File
|
|
190
199
|
|
191
200
|
lister = IO.popen("#{tags[:payloadcompressor]} -d | cpio -it --quiet", "r+")
|
192
201
|
buffer = ""
|
193
|
-
|
202
|
+
begin
|
203
|
+
buffer.force_encoding("BINARY")
|
204
|
+
rescue NoMethodError
|
205
|
+
# Do Nothing
|
206
|
+
end
|
194
207
|
payload_fd = payload.clone
|
195
208
|
output = ""
|
196
209
|
loop do
|
@@ -202,12 +215,23 @@ class RPM::File
|
|
202
215
|
begin
|
203
216
|
output << lister.read_nonblock(16384)
|
204
217
|
rescue Errno::EAGAIN
|
205
|
-
#
|
218
|
+
# Nothing to read, move on!
|
206
219
|
end
|
207
220
|
end
|
208
221
|
lister.close_write
|
222
|
+
|
209
223
|
# Read remaining output
|
210
|
-
|
224
|
+
begin
|
225
|
+
output << lister.read
|
226
|
+
rescue Errno::EAGAIN
|
227
|
+
# Because read_nonblock enables NONBLOCK the 'lister' fd,
|
228
|
+
# and we may have invoked a read *before* cpio has started
|
229
|
+
# writing, let's keep retrying this read until we get an EOF
|
230
|
+
retry
|
231
|
+
rescue EOFError
|
232
|
+
# At EOF, hurray! We're done reading.
|
233
|
+
end
|
234
|
+
|
211
235
|
# Split output by newline and strip leading "."
|
212
236
|
@files = output.split("\n").collect { |s| s.gsub(/^\./, "") }
|
213
237
|
return @files
|