minitar 0.9 → 0.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'archive/tar/minitar/reader'
3
+ require "archive/tar/minitar/reader"
4
4
 
5
5
  module Archive::Tar::Minitar
6
6
  # Wraps a Archive::Tar::Minitar::Reader with convenience methods and wrapped
@@ -51,7 +51,7 @@ module Archive::Tar::Minitar
51
51
  def self.each_entry(input)
52
52
  return to_enum(__method__, input) unless block_given?
53
53
 
54
- open(input) do |stream|
54
+ Input.open(input) do |stream|
55
55
  stream.each do |entry|
56
56
  yield entry
57
57
  end
@@ -71,10 +71,10 @@ module Archive::Tar::Minitar
71
71
  # Archive::Tar::Minitar::Input.new(path) -> input
72
72
  def initialize(input)
73
73
  @io = if input.respond_to?(:read)
74
- input
75
- else
76
- ::Kernel.open(input, 'rb')
77
- end
74
+ input
75
+ else
76
+ ::Kernel.open(input, "rb")
77
+ end
78
78
 
79
79
  unless Archive::Tar::Minitar.seekable?(@io, :rewind)
80
80
  raise Archive::Tar::Minitar::NonSeekableStream
@@ -96,7 +96,7 @@ module Archive::Tar::Minitar
96
96
  ensure
97
97
  @tar.rewind
98
98
  end
99
- alias each each_entry
99
+ alias_method :each, :each_entry
100
100
 
101
101
  # Extracts the current +entry+ to +destdir+. If a block is provided, it
102
102
  # yields an +action+ Symbol, the full name of the file being extracted
@@ -119,9 +119,9 @@ module Archive::Tar::Minitar
119
119
  # Reader::EntryStream, with all methods thereof.
120
120
  def extract_entry(destdir, entry, options = {}, &block) # :yields action, name, stats:
121
121
  stats = {
122
- :current => 0,
123
- :currinc => 0,
124
- :entry => entry
122
+ :current => 0,
123
+ :currinc => 0,
124
+ :entry => entry
125
125
  }
126
126
 
127
127
  # extract_entry is not vulnerable to prefix '/' vulnerabilities, but it
@@ -133,10 +133,10 @@ module Archive::Tar::Minitar
133
133
  # leave +destdir+.
134
134
  #
135
135
  # However, squeeze consecutive '/' characters together.
136
- full_name = entry.full_name.squeeze('/')
136
+ full_name = entry.full_name.squeeze("/")
137
137
 
138
- if full_name =~ /\.{2}(?:\/|\z)/
139
- raise SecureRelativePathError, %q(Path contains '..')
138
+ if /\.{2}(?:\/|\z)/.match?(full_name)
139
+ raise SecureRelativePathError, "Path contains '..'"
140
140
  end
141
141
 
142
142
  if entry.directory?
@@ -164,7 +164,7 @@ module Archive::Tar::Minitar
164
164
 
165
165
  def fsync_dir(dirname)
166
166
  # make sure this hits the disc
167
- dir = open(dirname, 'rb')
167
+ dir = IO.open(dirname, "rb")
168
168
  dir.fsync
169
169
  rescue # ignore IOError if it's an unpatched (old) Ruby
170
170
  nil
@@ -184,7 +184,7 @@ module Archive::Tar::Minitar
184
184
  nil
185
185
  end
186
186
  else
187
- File.unlink(dest.chomp('/')) if File.symlink?(dest.chomp('/'))
187
+ File.unlink(dest.chomp("/")) if File.symlink?(dest.chomp("/"))
188
188
 
189
189
  FileUtils.mkdir_p(dest, :mode => entry.mode)
190
190
  FileUtils.chmod(entry.mode, dest)
@@ -192,7 +192,7 @@ module Archive::Tar::Minitar
192
192
 
193
193
  if options.fetch(:fsync, true)
194
194
  fsync_dir(dest)
195
- fsync_dir(File.join(dest, '..'))
195
+ fsync_dir(File.join(dest, ".."))
196
196
  end
197
197
  end
198
198
 
@@ -211,7 +211,7 @@ module Archive::Tar::Minitar
211
211
 
212
212
  yield :file_start, full_name, stats if block_given?
213
213
 
214
- File.open(destfile, 'wb', entry.mode) do |os|
214
+ File.open(destfile, "wb", entry.mode) do |os|
215
215
  loop do
216
216
  data = entry.read(4096)
217
217
  break unless data
@@ -234,7 +234,7 @@ module Archive::Tar::Minitar
234
234
  yield :dir_fsync, full_name, stats if block_given?
235
235
 
236
236
  fsync_dir(File.dirname(destfile))
237
- fsync_dir(File.join(File.dirname(destfile), '..'))
237
+ fsync_dir(File.join(File.dirname(destfile), ".."))
238
238
  end
239
239
 
240
240
  yield :file_done, full_name, stats if block_given?
@@ -1,6 +1,6 @@
1
1
  # coding: utf-8
2
2
 
3
- require 'archive/tar/minitar/writer'
3
+ require "archive/tar/minitar/writer"
4
4
 
5
5
  module Archive::Tar::Minitar
6
6
  # Wraps a Archive::Tar::Minitar::Writer with convenience methods and wrapped
@@ -40,7 +40,7 @@ module Archive::Tar::Minitar
40
40
  def self.tar(output)
41
41
  return to_enum(__method__, output) unless block_given?
42
42
 
43
- open(output) do |stream|
43
+ Output.open(output) do |stream|
44
44
  yield stream.tar
45
45
  end
46
46
  end
@@ -55,10 +55,10 @@ module Archive::Tar::Minitar
55
55
  # Archive::Tar::Minitar::Output.new(path) -> output
56
56
  def initialize(output)
57
57
  @io = if output.respond_to?(:write)
58
- output
59
- else
60
- ::Kernel.open(output, 'wb')
61
- end
58
+ output
59
+ else
60
+ ::Kernel.open(output, "wb")
61
+ end
62
62
  @tar = Archive::Tar::Minitar::Writer.new(@io)
63
63
  end
64
64
 
@@ -2,8 +2,10 @@
2
2
 
3
3
  ##
4
4
  module Archive; end
5
+
5
6
  ##
6
7
  module Archive::Tar; end
8
+
7
9
  ##
8
10
  module Archive::Tar::Minitar; end
9
11
 
@@ -36,12 +38,12 @@ module Archive::Tar::Minitar; end
36
38
  # unrecognized typeflag value as a regular file."
37
39
  class Archive::Tar::Minitar::PosixHeader
38
40
  BLOCK_SIZE = 512
39
- MAGIC_BYTES = 'ustar'.freeze
41
+ MAGIC_BYTES = "ustar".freeze
40
42
 
41
- GNU_EXT_LONG_LINK = '././@LongLink'
43
+ GNU_EXT_LONG_LINK = "././@LongLink"
42
44
 
43
45
  # Fields that must be set in a POSIX tar(1) header.
44
- REQUIRED_FIELDS = [ :name, :size, :prefix, :mode ].freeze
46
+ REQUIRED_FIELDS = [:name, :size, :prefix, :mode].freeze
45
47
  # Fields that may be set in a POSIX tar(1) header.
46
48
  OPTIONAL_FIELDS = [
47
49
  :uid, :gid, :mtime, :checksum, :typeflag, :linkname, :magic, :version,
@@ -60,9 +62,9 @@ class Archive::Tar::Minitar::PosixHeader
60
62
  attr_accessor :name
61
63
 
62
64
  # The pack format passed to Array#pack for encoding a header.
63
- HEADER_PACK_FORMAT = 'a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155'.freeze
65
+ HEADER_PACK_FORMAT = "a100a8a8a8a12a12a7aaa100a6a2a32a32a8a8a155".freeze
64
66
  # The unpack format passed to String#unpack for decoding a header.
65
- HEADER_UNPACK_FORMAT = 'Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155'.freeze
67
+ HEADER_UNPACK_FORMAT = "Z100A8A8A8A12A12A8aZ100A6A2Z32Z32A8A8Z155".freeze
66
68
 
67
69
  class << self
68
70
  # Creates a new PosixHeader from a data stream.
@@ -79,23 +81,23 @@ class Archive::Tar::Minitar::PosixHeader
79
81
 
80
82
  # Creates a new PosixHeader from a BLOCK_SIZE-byte data buffer.
81
83
  def from_data(data)
82
- fields = data.unpack(HEADER_UNPACK_FORMAT)
83
- name = fields.shift
84
- mode = fields.shift.oct
85
- uid = fields.shift.oct
86
- gid = fields.shift.oct
87
- size = strict_oct(fields.shift)
88
- mtime = fields.shift.oct
89
- checksum = fields.shift.oct
90
- typeflag = fields.shift
91
- linkname = fields.shift
92
- magic = fields.shift
93
- version = fields.shift.oct
94
- uname = fields.shift
95
- gname = fields.shift
96
- devmajor = fields.shift.oct
97
- devminor = fields.shift.oct
98
- prefix = fields.shift
84
+ fields = data.unpack(HEADER_UNPACK_FORMAT)
85
+ name = fields.shift
86
+ mode = fields.shift.oct
87
+ uid = fields.shift.oct
88
+ gid = fields.shift.oct
89
+ size = strict_oct(fields.shift)
90
+ mtime = fields.shift.oct
91
+ checksum = fields.shift.oct
92
+ typeflag = fields.shift
93
+ linkname = fields.shift
94
+ magic = fields.shift
95
+ version = fields.shift.oct
96
+ uname = fields.shift
97
+ gname = fields.shift
98
+ devmajor = fields.shift.oct
99
+ devminor = fields.shift.oct
100
+ prefix = fields.shift
99
101
 
100
102
  empty = !data.each_byte.any?(&:nonzero?)
101
103
 
@@ -123,7 +125,7 @@ class Archive::Tar::Minitar::PosixHeader
123
125
  private
124
126
 
125
127
  def strict_oct(string)
126
- return string.oct if string =~ /\A[0-7 ]*\z/
128
+ return string.oct if /\A[0-7 ]*\z/.match?(string)
127
129
  raise ArgumentError, "#{string.inspect} is not a valid octal string"
128
130
  end
129
131
  end
@@ -136,13 +138,13 @@ class Archive::Tar::Minitar::PosixHeader
136
138
  end
137
139
 
138
140
  v[:mtime] = v[:mtime].to_i
139
- v[:checksum] ||= ''
140
- v[:typeflag] ||= '0'
141
- v[:magic] ||= MAGIC_BYTES
142
- v[:version] ||= '00'
141
+ v[:checksum] ||= ""
142
+ v[:typeflag] ||= "0"
143
+ v[:magic] ||= MAGIC_BYTES
144
+ v[:version] ||= "00"
143
145
 
144
146
  FIELDS.each do |f|
145
- instance_variable_set("@#{f}", v[f])
147
+ instance_variable_set(:"@#{f}", v[f])
146
148
  end
147
149
 
148
150
  @empty = v[:empty]
@@ -161,7 +163,7 @@ class Archive::Tar::Minitar::PosixHeader
161
163
  # Returns +true+ if the header is a long name special header which indicates
162
164
  # that the next block of data is the filename.
163
165
  def long_name?
164
- typeflag == 'L' && name == GNU_EXT_LONG_LINK
166
+ typeflag == "L" && name == GNU_EXT_LONG_LINK
165
167
  end
166
168
 
167
169
  # A string representation of the header.
@@ -169,11 +171,11 @@ class Archive::Tar::Minitar::PosixHeader
169
171
  update_checksum
170
172
  header(@checksum)
171
173
  end
172
- alias to_str to_s
174
+ alias_method :to_str, :to_s
173
175
 
174
176
  # Update the checksum field.
175
177
  def update_checksum
176
- hh = header(' ' * 8)
178
+ hh = header(" " * 8)
177
179
  @checksum = oct(calculate_checksum(hh), 6)
178
180
  end
179
181
 
@@ -190,13 +192,13 @@ class Archive::Tar::Minitar::PosixHeader
190
192
  end
191
193
 
192
194
  def calculate_checksum(hdr)
193
- hdr.unpack('C*').inject { |a, e| a + e }
195
+ hdr.unpack("C*").inject { |a, e| a + e }
194
196
  end
195
197
 
196
198
  def header(chksum)
197
199
  arr = [name, oct(mode, 7), oct(uid, 7), oct(gid, 7), oct(size, 11),
198
- oct(mtime, 11), chksum, ' ', typeflag, linkname, magic, version,
199
- uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
200
+ oct(mtime, 11), chksum, " ", typeflag, linkname, magic, version,
201
+ uname, gname, oct(devmajor, 7), oct(devminor, 7), prefix]
200
202
  str = arr.pack(HEADER_PACK_FORMAT)
201
203
  str + "\0" * ((BLOCK_SIZE - bytesize(str)) % BLOCK_SIZE)
202
204
  end
@@ -11,14 +11,21 @@ module Archive::Tar::Minitar
11
11
  # This marks the EntryStream closed for reading without closing the
12
12
  # actual data stream.
13
13
  module InvalidEntryStream
14
- # rubocop:disable Style/SingleLineMethods
15
- # rubocop:disable Style/EmptyLineBetweenDefs
16
- def read(*); raise ClosedStream; end
17
- def getc; raise ClosedStream; end
18
- def rewind; raise ClosedStream; end
19
- def closed?; true; end
20
- # rubocop:enable Style/EmptyLineBetweenDefs
21
- # rubocop:enable Style/SingleLineMethods Style/EmptyLineBetweenDefs
14
+ def read(*)
15
+ raise ClosedStream
16
+ end
17
+
18
+ def getc
19
+ raise ClosedStream
20
+ end
21
+
22
+ def rewind
23
+ raise ClosedStream
24
+ end
25
+
26
+ def closed?
27
+ true
28
+ end
22
29
  end
23
30
 
24
31
  # EntryStreams are pseudo-streams on top of the main data stream.
@@ -30,24 +37,24 @@ module Archive::Tar::Minitar
30
37
  end
31
38
 
32
39
  def initialize(header, io)
33
- @io = io
34
- @name = header.name
35
- @mode = header.mode
36
- @uid = header.uid
37
- @gid = header.gid
38
- @size = header.size
39
- @mtime = header.mtime
40
+ @io = io
41
+ @name = header.name
42
+ @mode = header.mode
43
+ @uid = header.uid
44
+ @gid = header.gid
45
+ @size = header.size
46
+ @mtime = header.mtime
40
47
  @checksum = header.checksum
41
48
  @typeflag = header.typeflag
42
49
  @linkname = header.linkname
43
- @magic = header.magic
44
- @version = header.version
45
- @uname = header.uname
46
- @gname = header.gname
50
+ @magic = header.magic
51
+ @version = header.version
52
+ @uname = header.uname
53
+ @gname = header.gname
47
54
  @devmajor = header.devmajor
48
55
  @devminor = header.devminor
49
- @prefix = header.prefix
50
- @read = 0
56
+ @prefix = header.prefix
57
+ @read = 0
51
58
  @orig_pos =
52
59
  if Archive::Tar::Minitar.seekable?(@io)
53
60
  @io.pos
@@ -79,25 +86,25 @@ module Archive::Tar::Minitar
79
86
  # Returns +true+ if the entry represents a directory.
80
87
  def directory?
81
88
  case @typeflag
82
- when '5'
89
+ when "5"
83
90
  true
84
- when '0', "\0"
91
+ when "0", "\0"
85
92
  # If the name ends with a slash, treat it as a directory.
86
93
  # This is what other major tar implementations do for
87
94
  # interoperability and compatibility with older tar variants
88
95
  # and some new ones.
89
- @name.end_with?('/')
96
+ @name.end_with?("/")
90
97
  else
91
98
  false
92
99
  end
93
100
  end
94
- alias directory directory?
101
+ alias_method :directory, :directory?
95
102
 
96
103
  # Returns +true+ if the entry represents a plain file.
97
104
  def file?
98
- (@typeflag == '0' || @typeflag == "\0") && !@name.end_with?('/')
105
+ (@typeflag == "0" || @typeflag == "\0") && !@name.end_with?("/")
99
106
  end
100
- alias file file?
107
+ alias_method :file, :file?
101
108
 
102
109
  # Returns +true+ if the current read pointer is at the end of the
103
110
  # EntryStream data.
@@ -125,7 +132,7 @@ module Archive::Tar::Minitar
125
132
 
126
133
  # Returns the full and proper name of the entry.
127
134
  def full_name
128
- if @prefix != ''
135
+ if @prefix != ""
129
136
  File.join(@prefix, @name)
130
137
  else
131
138
  @name
@@ -185,7 +192,7 @@ module Archive::Tar::Minitar
185
192
  def self.each_entry(io)
186
193
  return to_enum(__method__, io) unless block_given?
187
194
 
188
- open(io) do |reader|
195
+ Input.open(io) do |reader|
189
196
  reader.each_entry do |entry|
190
197
  yield entry
191
198
  end
@@ -195,7 +202,11 @@ module Archive::Tar::Minitar
195
202
  # Creates and returns a new Reader object.
196
203
  def initialize(io)
197
204
  @io = io
198
- @init_pos = io.pos rescue nil
205
+ @init_pos = begin
206
+ io.pos
207
+ rescue
208
+ nil
209
+ end
199
210
  end
200
211
 
201
212
  # Resets the read pointer to the beginning of data stream. Do not call
@@ -229,14 +240,17 @@ module Archive::Tar::Minitar
229
240
  raise Archive::Tar::Minitar::InvalidTarStream if header.size < 0
230
241
 
231
242
  if header.long_name?
232
- name = @io.read(512).rstrip
243
+ name_block = (header.size / 512.0).ceil * 512
244
+
245
+ name = @io.read(name_block).rstrip
233
246
  header = PosixHeader.from_stream(@io)
247
+
234
248
  return if header.empty?
235
249
  header.name = name
236
250
  end
237
251
 
238
252
  entry = EntryStream.new(header, @io)
239
- size = entry.size
253
+ size = entry.size
240
254
 
241
255
  yield entry
242
256
 
@@ -259,7 +273,7 @@ module Archive::Tar::Minitar
259
273
  entry.close
260
274
  end
261
275
  end
262
- alias each each_entry
276
+ alias_method :each, :each_entry
263
277
 
264
278
  # Returns false if the reader is open (it never closes).
265
279
  def closed?
@@ -30,8 +30,8 @@ module Archive::Tar::Minitar
30
30
  def self.const_missing(c)
31
31
  case c
32
32
  when :FileOverflow
33
- warn 'Writer::BoundedWriteStream::FileOverflow has been renamed ' \
34
- 'to Writer::WriteBoundaryOverflow'
33
+ warn "Writer::BoundedWriteStream::FileOverflow has been renamed " \
34
+ "to Writer::WriteBoundaryOverflow"
35
35
  const_set :FileOverflow,
36
36
  Archive::Tar::Minitar::Writer::WriteBoundaryOverflow
37
37
  else
@@ -46,9 +46,9 @@ module Archive::Tar::Minitar
46
46
  attr_reader :written
47
47
 
48
48
  def initialize(io, limit)
49
- @io = io
50
- @limit = limit
51
- @written = 0
49
+ @io = io
50
+ @limit = limit
51
+ @written = 0
52
52
  end
53
53
 
54
54
  def write(data)
@@ -65,7 +65,7 @@ module Archive::Tar::Minitar
65
65
  def self.const_missing(c)
66
66
  case c
67
67
  when :BoundedStream
68
- warn 'BoundedStream has been renamed to BoundedWriteStream'
68
+ warn "BoundedStream has been renamed to BoundedWriteStream"
69
69
  const_set(:BoundedStream, BoundedWriteStream)
70
70
  else
71
71
  super
@@ -101,7 +101,7 @@ module Archive::Tar::Minitar
101
101
 
102
102
  # Creates and returns a new Writer object.
103
103
  def initialize(io)
104
- @io = io
104
+ @io = io
105
105
  @closed = false
106
106
  end
107
107
 
@@ -139,10 +139,10 @@ module Archive::Tar::Minitar
139
139
  raise ClosedStream if @closed
140
140
 
141
141
  header = {
142
- :mode => opts.fetch(:mode, 0o644),
143
- :mtime => opts.fetch(:mtime, nil),
144
- :gid => opts.fetch(:gid, nil),
145
- :uid => opts.fetch(:uid, nil)
142
+ :mode => opts.fetch(:mode, 0o644),
143
+ :mtime => opts.fetch(:mtime, nil),
144
+ :gid => opts.fetch(:gid, nil),
145
+ :uid => opts.fetch(:uid, nil)
146
146
  }
147
147
 
148
148
  data = opts.fetch(:data, nil)
@@ -151,12 +151,12 @@ module Archive::Tar::Minitar
151
151
  if block_given?
152
152
  if data
153
153
  raise ArgumentError,
154
- 'Too much data (opts[:data] and block_given?).'
154
+ "Too much data (opts[:data] and block_given?)."
155
155
  end
156
156
 
157
- raise ArgumentError, 'No size provided' unless size
157
+ raise ArgumentError, "No size provided" unless size
158
158
  else
159
- raise ArgumentError, 'No data provided' unless data
159
+ raise ArgumentError, "No data provided" unless data
160
160
 
161
161
  bytes = bytesize(data)
162
162
  size = bytes if size.nil? || size < bytes
@@ -164,7 +164,8 @@ module Archive::Tar::Minitar
164
164
 
165
165
  header[:size] = size
166
166
 
167
- write_header(name, header)
167
+ short_name, prefix, needs_long_name = split_name(name)
168
+ write_header(header, name, short_name, prefix, needs_long_name)
168
169
 
169
170
  os = BoundedWriteStream.new(@io, size)
170
171
  if block_given?
@@ -211,12 +212,15 @@ module Archive::Tar::Minitar
211
212
  raise Archive::Tar::Minitar::NonSeekableStream
212
213
  end
213
214
 
215
+ short_name, prefix, needs_long_name = split_name(name)
216
+
217
+ data_offset = needs_long_name ? 3 * 512 : 512
214
218
  init_pos = @io.pos
215
- @io.write("\0" * 512) # placeholder for the header
219
+ @io.write("\0" * data_offset) # placeholder for the header
216
220
 
217
221
  yield WriteOnlyStream.new(@io), opts
218
222
 
219
- size = @io.pos - (init_pos + 512)
223
+ size = @io.pos - (init_pos + data_offset)
220
224
  remainder = (512 - (size % 512)) % 512
221
225
  @io.write("\0" * remainder)
222
226
 
@@ -227,9 +231,11 @@ module Archive::Tar::Minitar
227
231
  :mtime => opts[:mtime],
228
232
  :size => size,
229
233
  :gid => opts[:gid],
230
- :uid => opts[:uid],
234
+ :uid => opts[:uid]
231
235
  }
232
- write_header(name, header)
236
+
237
+ write_header(header, name, short_name, prefix, needs_long_name)
238
+
233
239
  @io.pos = final_pos
234
240
  end
235
241
 
@@ -239,13 +245,38 @@ module Archive::Tar::Minitar
239
245
 
240
246
  header = {
241
247
  :mode => opts[:mode],
242
- :typeflag => '5',
248
+ :typeflag => "5",
249
+ :size => 0,
250
+ :gid => opts[:gid],
251
+ :uid => opts[:uid],
252
+ :mtime => opts[:mtime]
253
+ }
254
+
255
+ short_name, prefix, needs_long_name = split_name(name)
256
+ write_header(header, name, short_name, prefix, needs_long_name)
257
+
258
+ nil
259
+ end
260
+
261
+ # Creates a symbolic link entry in the tar.
262
+ def symlink(name, link_target, opts = {})
263
+ raise ClosedStream if @closed
264
+
265
+ raise FileNameTooLong if link_target.size > 100
266
+
267
+ name, prefix = split_name(name)
268
+ header = {
269
+ :name => name,
270
+ :mode => opts[:mode],
271
+ :typeflag => "2",
243
272
  :size => 0,
273
+ :linkname => link_target,
244
274
  :gid => opts[:gid],
245
275
  :uid => opts[:uid],
246
276
  :mtime => opts[:mtime],
277
+ :prefix => prefix
247
278
  }
248
- write_header(name, header)
279
+ @io.write(PosixHeader.new(header))
249
280
  nil
250
281
  end
251
282
 
@@ -271,47 +302,45 @@ module Archive::Tar::Minitar
271
302
 
272
303
  private
273
304
 
274
- def write_header(long_name, header)
275
- short_name, prefix, needs_long_name = split_name(long_name)
276
-
305
+ def write_header(header, long_name, short_name, prefix, needs_long_name)
277
306
  if needs_long_name
278
307
  long_name_header = {
279
- :prefix => '',
308
+ :prefix => "",
280
309
  :name => PosixHeader::GNU_EXT_LONG_LINK,
281
- :typeflag => 'L',
282
- :size => long_name.length,
283
- :mode => 0,
310
+ :typeflag => "L",
311
+ :size => long_name.length + 1,
312
+ :mode => 0
284
313
  }
285
314
  @io.write(PosixHeader.new(long_name_header))
286
315
  @io.write(long_name)
287
316
  @io.write("\0" * (512 - (long_name.length % 512)))
288
317
  end
289
318
 
290
- new_header = header.merge({ :name => short_name, :prefix => prefix })
319
+ new_header = header.merge({:name => short_name, :prefix => prefix})
291
320
  @io.write(PosixHeader.new(new_header))
292
321
  end
293
322
 
294
323
  def split_name(name)
295
324
  if bytesize(name) <= 100
296
- prefix = ''
325
+ prefix = ""
297
326
  else
298
- parts = name.split(/\//)
327
+ parts = name.split("/")
299
328
  newname = parts.pop
300
329
 
301
- nxt = ''
330
+ nxt = ""
302
331
 
303
332
  loop do
304
- nxt = parts.pop || ''
333
+ nxt = parts.pop || ""
305
334
  break if bytesize(newname) + 1 + bytesize(nxt) >= 100
306
335
  newname = "#{nxt}/#{newname}"
307
336
  end
308
337
 
309
- prefix = (parts + [nxt]).join('/')
338
+ prefix = (parts + [nxt]).join("/")
310
339
 
311
340
  name = newname
312
341
  end
313
342
 
314
- [ name, prefix, (bytesize(name) > 100 || bytesize(prefix) > 155) ]
343
+ [name, prefix, bytesize(name) > 100 || bytesize(prefix) > 155]
315
344
  end
316
345
  end
317
346
  end