arr-pm 0.0.9 → 0.0.10

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.

checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ZTNjMjFhNWE2MmQ0MDhhOWZlNjBhZDYwNzI3MzI5NTM4MTMyZTJlYQ==
5
- data.tar.gz: !binary |-
6
- NDllNDRiN2NhODY3ZmRhNDYxNTk5MmU4OTA4Y2FmZTA3NDhkYWZkOQ==
2
+ SHA1:
3
+ metadata.gz: 60fcb2287ddbb0f718255da5beb0033d9459be16
4
+ data.tar.gz: 1586517c23d99e2c5dead4a45128cfd49c9ff87c
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- ZTAwZWViMjNkZWI4MmJmMjFhNjI2MGNiYmIyZmFjNjhkNGI4ZmQwMjU1NDY5
10
- YWY4YjY5MmE2MGNmMTNkYWI0MDRiMTdmZTg0ODE4YmM5MzU3YWY0M2JjYmNl
11
- NGM0ZGUzYWIwZmIzODE4ODI4MzVjMzY1NDhhYTJiNjI2NjcyN2U=
12
- data.tar.gz: !binary |-
13
- MWNkZWU2ODFlMmMxNzEzOTYzYzllMTIwN2Y3YjBmYTc0ZjE2M2I1YjljYWFk
14
- NjFhM2VkZmVhYjNmYzIxNzE1YTZjNzFkZjExMmMzMDRjYjA2MzA2MDc3MjI3
15
- N2VmYWU0YjBhZTlhM2FkZGUxMGYzMmFhMWIwZmM0MWNiMmI1NjE=
6
+ metadata.gz: e44130d06daa88d4b84b0c800fb54dd8ca8cb4f0b75185c98e450e6b241d30fe666e4a491c6a8113c837d162b95783dcd805c293b1af5fc0d99b2e74ad86eb30
7
+ data.tar.gz: 1c7b02c83d66bcc5964faeeab66b3cc179acda31225039ba60ef0e05311ab9824887830e2ee568ef7946e18d594b274e11141fde2b92eb4a3418c3b85123abd0
@@ -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
@@ -1 +1,3 @@
1
- source :rubygems
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
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
 
@@ -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.9"
5
+ spec.version = "0.0.10"
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
@@ -177,6 +177,8 @@ class RPM::File
177
177
  def config_files
178
178
  # this stuff seems to be in the 'enum rpmfileAttrs_e' from rpm/rpmfi.h
179
179
  results = []
180
+ # short-circuit if there's no :fileflags tag
181
+ return results unless tags.include?(:fileflags)
180
182
  tags[:fileflags].each_with_index do |flag, i|
181
183
  # The :fileflags (and other :file... tags) are an array, in order of
182
184
  # files in the rpm payload, we want a list of paths of config files.
metadata CHANGED
@@ -1,27 +1,41 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arr-pm
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-02-05 00:00:00.000000000 Z
11
+ date: 2015-04-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cabin
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>'
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ! '>'
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: flores
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">"
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">"
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
27
41
  description: This library allows to you to read and write rpm packages. Written in
@@ -32,14 +46,15 @@ executables: []
32
46
  extensions: []
33
47
  extra_rdoc_files: []
34
48
  files:
35
- - .batcave/manifest
36
- - .gitignore
49
+ - ".batcave/manifest"
50
+ - ".gitignore"
51
+ - ".rubocop.yml"
37
52
  - Gemfile
38
53
  - LICENSE
39
54
  - Makefile
40
55
  - README.md
41
56
  - arr-pm.gemspec
42
- - header-verify.rb
57
+ - cpio.rb
43
58
  - lib/arr-pm.rb
44
59
  - lib/arr-pm/conflicts.rb
45
60
  - lib/arr-pm/file.rb
@@ -48,8 +63,6 @@ files:
48
63
  - lib/arr-pm/file/tag.rb
49
64
  - lib/arr-pm/namespace.rb
50
65
  - lib/arr-pm/requires.rb
51
- - notify-failure.sh
52
- - printrpm.rb
53
66
  homepage:
54
67
  licenses:
55
68
  - Apache 2
@@ -61,19 +74,18 @@ require_paths:
61
74
  - lib
62
75
  required_ruby_version: !ruby/object:Gem::Requirement
63
76
  requirements:
64
- - - ! '>='
77
+ - - ">="
65
78
  - !ruby/object:Gem::Version
66
79
  version: '0'
67
80
  required_rubygems_version: !ruby/object:Gem::Requirement
68
81
  requirements:
69
- - - ! '>='
82
+ - - ">="
70
83
  - !ruby/object:Gem::Version
71
84
  version: '0'
72
85
  requirements: []
73
86
  rubyforge_project:
74
- rubygems_version: 2.1.11
87
+ rubygems_version: 2.4.3
75
88
  signing_key:
76
89
  specification_version: 4
77
90
  summary: RPM reader and writer library
78
91
  test_files: []
79
- has_rdoc:
@@ -1,71 +0,0 @@
1
- HEADER_MAGIC = "\x8e\xad\xe8\x01\x00\x00\x00\x00"
2
- TAG_ENTRY_SIZE = 16 # tag id, type, offset, count == 16 bytes
3
-
4
- def read_header(io)
5
- # RPM 'header' section looks like:
6
- #
7
- # MAGIC (8 bytes) index_count (4 bytes), data_length (4 bytes )
8
- #
9
- # * index_count is the number of 'tags' in this header.
10
- # * data_length is a blob containing all the values for the tags
11
- #
12
- # Header has a header of 'magic' + index_count (4 bytes) + data_length (4 bytes)
13
- #p "start of header" => io.pos
14
- data = io.read(16).unpack("a8NN")
15
-
16
- # TODO(sissel): @index_count is really a count, rename?
17
- @magic, @index_count, @data_length = data
18
- if @magic != HEADER_MAGIC
19
- puts "Magic value in header was wrong. Expected #{HEADER_MAGIC.inspect}, but got #{@magic.inspect}"
20
- exit 1
21
- end
22
-
23
- @index_size = @index_count * TAG_ENTRY_SIZE
24
- tag_data = io.read(@index_size)
25
- data = io.read(@data_length)
26
- #p "end of header" => io.pos
27
-
28
- (0 ... @index_count).each do |i|
29
- offset = i * TAG_ENTRY_SIZE
30
- entry_data = tag_data[i * TAG_ENTRY_SIZE, TAG_ENTRY_SIZE]
31
- tag, tag_type, offset, count = entry_data.unpack("NNNN")
32
- if block_given?
33
- yield :tag => tag, :type => tag_type, :offset => offset, :count => count
34
- end
35
- #entry << data
36
- end # each index
37
- return 16 + @index_size + @data_length
38
- end
39
-
40
- if ARGV.length != 1
41
- puts "Usage: #{$0} blah.rpm"
42
- exit 1
43
- end
44
-
45
- rpm = File.new(ARGV[0])
46
-
47
- # Read the 'lead' - it's mostly an ignored part of the rpm file.
48
- lead = rpm.read(96)
49
- magic, major, minor, type, archnum, name, osnum, signature_type, reserved = lead.unpack("A4CCnnA66nnA16")
50
-
51
- puts "RPM file version #{major}.#{minor} (#{signature_type == 5 ? "signed" : "unsigned"})"
52
-
53
- if signature_type == 5
54
- # Read a header for the rpm signature. This has the same format as a normal
55
- # rpm header
56
- puts "Checking signature"
57
- length = read_header(rpm) do |tag|
58
- # print each tag in this header
59
- p tag
60
- end
61
-
62
- # signature headers are padded up to an 8-byte boundar, details here:
63
- # http://rpm.org/gitweb?p=rpm.git;a=blob;f=lib/signature.c;h=63e59c00f255a538e48cbc8b0cf3b9bd4a4dbd56;hb=HEAD#l204
64
- # Throw away the pad.
65
- rpm.read((length % 8))
66
- end
67
-
68
- # Read the rpm header
69
- puts "Checking header"
70
- read_header(rpm)
71
- p rpm.read(4)
@@ -1,15 +0,0 @@
1
- #!/bin/sh
2
-
3
- "$@"
4
- status=$?
5
-
6
- if [ ! -z "$TMUX" ] ; then
7
- if [ "$status" -ne 0 ] ; then
8
- tmux display-message "Tests Fail"
9
- else
10
- tmux display-message "Tests OK"
11
- fi
12
- fi
13
-
14
- exit $status
15
-
@@ -1,22 +0,0 @@
1
- $: << "lib"
2
-
3
- require "rpm/file"
4
-
5
- rpm = RPM::File.new(ARGV[0])
6
-
7
- #p rpm.lead
8
- rpm.signature.tags.each do |tag|
9
- #p :tag => [tag.tag, tag.type, tag.count, tag.value]
10
- end
11
-
12
- rpm.header.tags.each do |tag|
13
- #next unless tag.tag.to_s =~ /(payload|sig)/
14
- # p :tag => [tag.tag, tag.type, tag.count, tag.value]
15
- end
16
-
17
- require "awesome_print"
18
- ap rpm.requires
19
-
20
- #payload = rpm.payload
21
- #fd = File.new("/tmp/rpm.payload", "w")
22
- #fd.write(rpm.payload.read)