fpm-aeppert 1.6.2
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.
- checksums.yaml +7 -0
- data/CHANGELIST +661 -0
- data/CONTRIBUTORS +26 -0
- data/LICENSE +21 -0
- data/bin/fpm +8 -0
- data/lib/fpm.rb +20 -0
- data/lib/fpm/command.rb +648 -0
- data/lib/fpm/errors.rb +4 -0
- data/lib/fpm/namespace.rb +4 -0
- data/lib/fpm/package.rb +539 -0
- data/lib/fpm/package/apk.rb +510 -0
- data/lib/fpm/package/cpan.rb +405 -0
- data/lib/fpm/package/deb.rb +935 -0
- data/lib/fpm/package/dir.rb +221 -0
- data/lib/fpm/package/empty.rb +13 -0
- data/lib/fpm/package/freebsd.rb +147 -0
- data/lib/fpm/package/gem.rb +243 -0
- data/lib/fpm/package/npm.rb +120 -0
- data/lib/fpm/package/osxpkg.rb +165 -0
- data/lib/fpm/package/p5p.rb +124 -0
- data/lib/fpm/package/pacman.rb +403 -0
- data/lib/fpm/package/pear.rb +117 -0
- data/lib/fpm/package/pkgin.rb +35 -0
- data/lib/fpm/package/pleaserun.rb +63 -0
- data/lib/fpm/package/puppet.rb +120 -0
- data/lib/fpm/package/pyfpm/__init__.py +1 -0
- data/lib/fpm/package/pyfpm/get_metadata.py +104 -0
- data/lib/fpm/package/python.rb +318 -0
- data/lib/fpm/package/rpm.rb +593 -0
- data/lib/fpm/package/sh.rb +69 -0
- data/lib/fpm/package/solaris.rb +95 -0
- data/lib/fpm/package/tar.rb +86 -0
- data/lib/fpm/package/virtualenv.rb +164 -0
- data/lib/fpm/package/zip.rb +63 -0
- data/lib/fpm/rake_task.rb +60 -0
- data/lib/fpm/util.rb +358 -0
- data/lib/fpm/util/tar_writer.rb +80 -0
- data/lib/fpm/version.rb +3 -0
- data/templates/deb.erb +52 -0
- data/templates/deb/changelog.erb +5 -0
- data/templates/deb/ldconfig.sh.erb +13 -0
- data/templates/deb/postinst_upgrade.sh.erb +62 -0
- data/templates/deb/postrm_upgrade.sh.erb +46 -0
- data/templates/deb/preinst_upgrade.sh.erb +41 -0
- data/templates/deb/prerm_upgrade.sh.erb +39 -0
- data/templates/osxpkg.erb +11 -0
- data/templates/p5p_metadata.erb +12 -0
- data/templates/pacman.erb +47 -0
- data/templates/pacman/INSTALL.erb +41 -0
- data/templates/pleaserun/generate-cleanup.sh +17 -0
- data/templates/pleaserun/install-path.sh +17 -0
- data/templates/pleaserun/install.sh +117 -0
- data/templates/pleaserun/scripts/after-install.sh +4 -0
- data/templates/pleaserun/scripts/before-remove.sh +12 -0
- data/templates/puppet/package.pp.erb +34 -0
- data/templates/puppet/package/remove.pp.erb +13 -0
- data/templates/rpm.erb +260 -0
- data/templates/rpm/filesystem_list +14514 -0
- data/templates/sh.erb +369 -0
- data/templates/solaris.erb +15 -0
- metadata +322 -0
@@ -0,0 +1,510 @@
|
|
1
|
+
require "erb"
|
2
|
+
require "fpm/namespace"
|
3
|
+
require "fpm/package"
|
4
|
+
require "fpm/errors"
|
5
|
+
require "fpm/util"
|
6
|
+
require "backports"
|
7
|
+
require "fileutils"
|
8
|
+
require "digest"
|
9
|
+
require 'digest/sha1'
|
10
|
+
|
11
|
+
# Support for debian packages (.deb files)
|
12
|
+
#
|
13
|
+
# This class supports both input and output of packages.
|
14
|
+
class FPM::Package::APK< FPM::Package
|
15
|
+
|
16
|
+
TAR_CHUNK_SIZE = 512
|
17
|
+
TAR_TYPEFLAG_OFFSET = 156
|
18
|
+
TAR_NAME_OFFSET_START = 0
|
19
|
+
TAR_NAME_OFFSET_END = 99
|
20
|
+
TAR_LENGTH_OFFSET_START = 124
|
21
|
+
TAR_LENGTH_OFFSET_END = 135
|
22
|
+
TAR_CHECKSUM_OFFSET_START = 148
|
23
|
+
TAR_CHECKSUM_OFFSET_END = 155
|
24
|
+
TAR_MAGIC_START = 257
|
25
|
+
TAR_MAGIC_END = 264
|
26
|
+
TAR_UID_START = 108
|
27
|
+
TAR_UID_END = 115
|
28
|
+
TAR_GID_START = 116
|
29
|
+
TAR_GID_END = 123
|
30
|
+
TAR_UNAME_START = 265
|
31
|
+
TAR_UNAME_END = 296
|
32
|
+
TAR_GNAME_START = 297
|
33
|
+
TAR_GNAME_END = 328
|
34
|
+
TAR_MAJOR_START = 329
|
35
|
+
TAR_MAJOR_END = 336
|
36
|
+
TAR_MINOR_START = 337
|
37
|
+
TAR_MINOR_END = 344
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
# Get the name of this package. See also FPM::Package#name
|
42
|
+
#
|
43
|
+
# This accessor actually modifies the name if it has some invalid or unwise
|
44
|
+
# characters.
|
45
|
+
def name
|
46
|
+
if @name =~ /[A-Z]/
|
47
|
+
logger.warn("apk packages should not have uppercase characters in their names")
|
48
|
+
@name = @name.downcase
|
49
|
+
end
|
50
|
+
|
51
|
+
if @name.include?("_")
|
52
|
+
logger.warn("apk packages should not include underscores")
|
53
|
+
@name = @name.gsub(/[_]/, "-")
|
54
|
+
end
|
55
|
+
|
56
|
+
if @name.include?(" ")
|
57
|
+
logger.warn("apk packages should not contain spaces")
|
58
|
+
@name = @name.gsub(/[ ]/, "-")
|
59
|
+
end
|
60
|
+
|
61
|
+
return @name
|
62
|
+
end
|
63
|
+
|
64
|
+
def prefix
|
65
|
+
return (attributes[:prefix] or "/")
|
66
|
+
end
|
67
|
+
|
68
|
+
def architecture
|
69
|
+
|
70
|
+
# "native" in apk should be "noarch"
|
71
|
+
if @architecture.nil? or @architecture == "native"
|
72
|
+
@architecture = "noarch"
|
73
|
+
end
|
74
|
+
return @architecture
|
75
|
+
end
|
76
|
+
|
77
|
+
def input(input_path)
|
78
|
+
logger.error("apk extraction is not yet implemented")
|
79
|
+
end
|
80
|
+
|
81
|
+
def output(output_path)
|
82
|
+
|
83
|
+
output_check(output_path)
|
84
|
+
|
85
|
+
control_path = build_path("control")
|
86
|
+
controltar_path = build_path("control.tar")
|
87
|
+
datatar_path = build_path("data.tar")
|
88
|
+
|
89
|
+
FileUtils.mkdir(control_path)
|
90
|
+
|
91
|
+
# data tar.
|
92
|
+
tar_path(staging_path(""), datatar_path)
|
93
|
+
|
94
|
+
# control tar.
|
95
|
+
begin
|
96
|
+
write_pkginfo(control_path)
|
97
|
+
write_control_scripts(control_path)
|
98
|
+
tar_path(control_path, controltar_path)
|
99
|
+
ensure
|
100
|
+
FileUtils.rm_r(control_path)
|
101
|
+
end
|
102
|
+
|
103
|
+
# concatenate the two into a real apk.
|
104
|
+
begin
|
105
|
+
|
106
|
+
# cut end-of-tar record from control tar
|
107
|
+
cut_tar_record(controltar_path)
|
108
|
+
|
109
|
+
# calculate/rewrite sha1 hashes for data tar
|
110
|
+
hash_datatar(datatar_path)
|
111
|
+
|
112
|
+
# concatenate the two into the final apk
|
113
|
+
concat_zip_tars(controltar_path, datatar_path, output_path)
|
114
|
+
end
|
115
|
+
|
116
|
+
logger.warn("apk output does not currently sign packages.")
|
117
|
+
logger.warn("It's recommended that your package be installed with '--allow-untrusted'")
|
118
|
+
end
|
119
|
+
|
120
|
+
def write_pkginfo(base_path)
|
121
|
+
|
122
|
+
pkginfo = ""
|
123
|
+
|
124
|
+
pkginfo << "# Generated by fpm\n"
|
125
|
+
pkginfo << "pkgname = #{@name}\n"
|
126
|
+
pkginfo << "pkgver = #{to_s("FULLVERSION")}\n"
|
127
|
+
pkginfo << "arch = #{architecture()}\n"
|
128
|
+
pkginfo << "pkgdesc = #{description()}\n"
|
129
|
+
pkginfo << "url = #{url()}\n"
|
130
|
+
pkginfo << "size = 102400\n" # totally magic, not sure what it's used for.
|
131
|
+
|
132
|
+
# write depends lines
|
133
|
+
for dependency in dependencies()
|
134
|
+
pkginfo << "depend = #{dependency}\n"
|
135
|
+
end
|
136
|
+
|
137
|
+
File.write("#{base_path}/.PKGINFO", pkginfo)
|
138
|
+
end
|
139
|
+
|
140
|
+
# Writes each control script from template into the build path,
|
141
|
+
# in the folder given by [base_path]
|
142
|
+
def write_control_scripts(base_path)
|
143
|
+
|
144
|
+
scripts = {}
|
145
|
+
|
146
|
+
scripts = register_script('post-install', :after_install, scripts)
|
147
|
+
scripts = register_script('post-install', :before_install, scripts)
|
148
|
+
scripts = register_script('post-install', :before_upgrade, scripts)
|
149
|
+
scripts = register_script('post-install', :after_upgrade, scripts)
|
150
|
+
scripts = register_script('pre-deinstall', :before_remove, scripts)
|
151
|
+
scripts = register_script('post-deinstall', :after_remove, scripts)
|
152
|
+
|
153
|
+
scripts.each do |key, content|
|
154
|
+
|
155
|
+
File.write("#{base_path}/.#{key}", content)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Convenience method for 'write_control_scripts' to register control scripts
|
160
|
+
# if they exist.
|
161
|
+
def register_script(key, value, hash)
|
162
|
+
|
163
|
+
if(script?(value))
|
164
|
+
hash[key] = scripts[value]
|
165
|
+
end
|
166
|
+
return hash
|
167
|
+
end
|
168
|
+
|
169
|
+
# Removes the end-of-tar records from the given [target_path].
|
170
|
+
# End of tar records are two contiguous empty tar records at the end of the file
|
171
|
+
# Taken together, they comprise 1k of null data.
|
172
|
+
def cut_tar_record(target_path)
|
173
|
+
|
174
|
+
temporary_target_path = target_path + "~"
|
175
|
+
|
176
|
+
record_length = 0
|
177
|
+
empty_records = 0
|
178
|
+
|
179
|
+
open(temporary_target_path, "wb") do |target_file|
|
180
|
+
|
181
|
+
# Scan to find the location of the two contiguous null records
|
182
|
+
open(target_path, "rb") do |file|
|
183
|
+
|
184
|
+
until(empty_records == 2)
|
185
|
+
|
186
|
+
header = file.read(TAR_CHUNK_SIZE)
|
187
|
+
|
188
|
+
# clear off ownership info
|
189
|
+
header = replace_ownership_headers(header, true)
|
190
|
+
|
191
|
+
typeflag = header[TAR_TYPEFLAG_OFFSET]
|
192
|
+
ascii_length = header[TAR_LENGTH_OFFSET_START..TAR_LENGTH_OFFSET_END]
|
193
|
+
|
194
|
+
if(file.eof?())
|
195
|
+
raise StandardError.new("Invalid tar stream, eof before end-of-tar record")
|
196
|
+
end
|
197
|
+
|
198
|
+
if(typeflag == "\0")
|
199
|
+
empty_records += 1
|
200
|
+
next
|
201
|
+
end
|
202
|
+
|
203
|
+
record_length = ascii_length.to_i(8)
|
204
|
+
record_length = determine_record_length(record_length)
|
205
|
+
|
206
|
+
target_file.write(header)
|
207
|
+
target_file.write(file.read(record_length))
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
FileUtils::mv(temporary_target_path, target_path)
|
213
|
+
end
|
214
|
+
|
215
|
+
# Rewrites the tar file located at the given [target_tar_path]
|
216
|
+
# to have its record headers use a simple checksum,
|
217
|
+
# and the apk sha1 hash extension.
|
218
|
+
def hash_datatar(target_path)
|
219
|
+
|
220
|
+
header = extension_header = ""
|
221
|
+
data = extension_data = ""
|
222
|
+
record_length = extension_length = 0
|
223
|
+
empty_records = 0
|
224
|
+
|
225
|
+
temporary_file_name = target_path + "~"
|
226
|
+
|
227
|
+
target_file = open(temporary_file_name, "wb")
|
228
|
+
file = open(target_path, "rb")
|
229
|
+
begin
|
230
|
+
|
231
|
+
until(file.eof?() || empty_records == 2)
|
232
|
+
|
233
|
+
header = file.read(TAR_CHUNK_SIZE)
|
234
|
+
typeflag = header[TAR_TYPEFLAG_OFFSET]
|
235
|
+
record_length = header[TAR_LENGTH_OFFSET_START..TAR_LENGTH_OFFSET_END].to_i(8)
|
236
|
+
|
237
|
+
data = ""
|
238
|
+
record_length = determine_record_length(record_length)
|
239
|
+
|
240
|
+
until(data.length == record_length)
|
241
|
+
data += file.read(TAR_CHUNK_SIZE)
|
242
|
+
end
|
243
|
+
|
244
|
+
# Clear ownership fields
|
245
|
+
header = replace_ownership_headers(header, false)
|
246
|
+
|
247
|
+
# If it's not a null record, do extension hash.
|
248
|
+
if(typeflag != "\0")
|
249
|
+
extension_header = header.dup()
|
250
|
+
|
251
|
+
extension_header = replace_ownership_headers(extension_header, true)
|
252
|
+
|
253
|
+
# directories have a magic string inserted into their name
|
254
|
+
full_record_path = extension_header[TAR_NAME_OFFSET_START..TAR_NAME_OFFSET_END].delete("\0")
|
255
|
+
full_record_path = add_paxstring(full_record_path)
|
256
|
+
|
257
|
+
# hash data contents with sha1, if there is any content.
|
258
|
+
if(typeflag == '5')
|
259
|
+
|
260
|
+
extension_data = ""
|
261
|
+
|
262
|
+
# ensure it doesn't end with a slash
|
263
|
+
if(full_record_path[full_record_path.length-1] == '/')
|
264
|
+
full_record_path = full_record_path.chop()
|
265
|
+
end
|
266
|
+
else
|
267
|
+
extension_data = hash_record(data)
|
268
|
+
end
|
269
|
+
|
270
|
+
full_record_path = pad_string_to(full_record_path, 100)
|
271
|
+
extension_header[TAR_NAME_OFFSET_START..TAR_NAME_OFFSET_END] = full_record_path
|
272
|
+
|
273
|
+
extension_header[TAR_TYPEFLAG_OFFSET] = 'x'
|
274
|
+
extension_header[TAR_LENGTH_OFFSET_START..TAR_LENGTH_OFFSET_END] = extension_data.length.to_s(8).rjust(12, '0')
|
275
|
+
extension_header = checksum_header(extension_header)
|
276
|
+
|
277
|
+
# write extension record
|
278
|
+
target_file.write(extension_header)
|
279
|
+
target_file.write(extension_data)
|
280
|
+
else
|
281
|
+
empty_records += 1
|
282
|
+
end
|
283
|
+
|
284
|
+
# write header and data to target file.
|
285
|
+
target_file.write(header)
|
286
|
+
target_file.write(data)
|
287
|
+
end
|
288
|
+
FileUtils.mv(temporary_file_name, target_path)
|
289
|
+
ensure
|
290
|
+
file.close()
|
291
|
+
target_file.close()
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
# Concatenates each of the given [apath] and [bpath] into the given [target_path]
|
296
|
+
def concat_zip_tars(apath, bpath, target_path)
|
297
|
+
|
298
|
+
temp_apath = apath + "~"
|
299
|
+
temp_bpath = bpath + "~"
|
300
|
+
|
301
|
+
# zip each path separately
|
302
|
+
Zlib::GzipWriter.open(temp_apath) do |target_writer|
|
303
|
+
open(apath, "rb") do |file|
|
304
|
+
until(file.eof?())
|
305
|
+
target_writer.write(file.read(4096))
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
Zlib::GzipWriter.open(temp_bpath) do |target_writer|
|
311
|
+
open(bpath, "rb") do |file|
|
312
|
+
until(file.eof?())
|
313
|
+
target_writer.write(file.read(4096))
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
# concat both into one.
|
319
|
+
File.open(target_path, "wb") do |target_writer|
|
320
|
+
open(temp_apath, "rb") do |file|
|
321
|
+
until(file.eof?())
|
322
|
+
target_writer.write(file.read(4096))
|
323
|
+
end
|
324
|
+
end
|
325
|
+
open(temp_bpath, "rb") do |file|
|
326
|
+
until(file.eof?())
|
327
|
+
target_writer.write(file.read(4096))
|
328
|
+
end
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# Rounds the given [record_length] to the nearest highest evenly-divisble number of 512.
|
334
|
+
def determine_record_length(record_length)
|
335
|
+
|
336
|
+
sans_size = TAR_CHUNK_SIZE-1
|
337
|
+
|
338
|
+
if(record_length % TAR_CHUNK_SIZE != 0)
|
339
|
+
record_length = (record_length + sans_size) & ~sans_size;
|
340
|
+
end
|
341
|
+
return record_length
|
342
|
+
end
|
343
|
+
|
344
|
+
# Checksums the entire contents of the given [header]
|
345
|
+
# Writes the resultant checksum into indices 148-155 of the same [header],
|
346
|
+
# and returns the modified header.
|
347
|
+
# 148-155 is the "size" range in a tar/ustar header.
|
348
|
+
def checksum_header(header)
|
349
|
+
|
350
|
+
# blank out header checksum
|
351
|
+
replace_string_range(header, TAR_CHECKSUM_OFFSET_START, TAR_CHECKSUM_OFFSET_END, ' ')
|
352
|
+
|
353
|
+
# calculate new checksum
|
354
|
+
checksum = 0
|
355
|
+
|
356
|
+
for i in 0..(TAR_CHUNK_SIZE-1)
|
357
|
+
checksum += header.getbyte(i)
|
358
|
+
end
|
359
|
+
|
360
|
+
checksum = checksum.to_s(8).rjust(6, '0')
|
361
|
+
header[TAR_CHECKSUM_OFFSET_START..TAR_CHECKSUM_OFFSET_END-2] = checksum
|
362
|
+
header[TAR_CHECKSUM_OFFSET_END-1] = "\0"
|
363
|
+
return header
|
364
|
+
end
|
365
|
+
|
366
|
+
# SHA-1 hashes the given data, then places it in the APK hash string format
|
367
|
+
# then returns.
|
368
|
+
def hash_record(data)
|
369
|
+
|
370
|
+
# %u %s=%s\n
|
371
|
+
# len name=hash
|
372
|
+
|
373
|
+
hash = Digest::SHA1.hexdigest(data)
|
374
|
+
name = "APK-TOOLS.checksum.SHA1"
|
375
|
+
|
376
|
+
ret = "#{name}=#{hash}\n"
|
377
|
+
|
378
|
+
# the length requirement needs to know its own length too, because the length
|
379
|
+
# is the entire length of the line, not just the contents.
|
380
|
+
length = ret.length
|
381
|
+
line_length = length.to_s
|
382
|
+
length += line_length.length
|
383
|
+
candidate_ret = "#{line_length} #{ret}"
|
384
|
+
|
385
|
+
if(candidate_ret.length != length)
|
386
|
+
length += 1
|
387
|
+
candidate_ret = "#{length.to_s} #{ret}"
|
388
|
+
end
|
389
|
+
|
390
|
+
ret = candidate_ret
|
391
|
+
|
392
|
+
# pad out the result
|
393
|
+
ret = pad_string_to(ret, TAR_CHUNK_SIZE)
|
394
|
+
return ret
|
395
|
+
end
|
396
|
+
|
397
|
+
# Tars the current contents of the given [path] to the given [target_path].
|
398
|
+
def tar_path(path, target_path)
|
399
|
+
|
400
|
+
# Change directory to the source path, and glob files
|
401
|
+
# This is done so that we end up with a "flat" archive, that doesn't
|
402
|
+
# have any path artifacts from the packager's absolute path.
|
403
|
+
::Dir::chdir(path) do
|
404
|
+
entries = ::Dir::glob("**", File::FNM_DOTMATCH)
|
405
|
+
|
406
|
+
args =
|
407
|
+
[
|
408
|
+
tar_cmd,
|
409
|
+
"-f",
|
410
|
+
target_path,
|
411
|
+
"-c"
|
412
|
+
]
|
413
|
+
|
414
|
+
# Move pkginfo to the front, if it exists.
|
415
|
+
for i in (0..entries.length)
|
416
|
+
if(entries[i] == ".PKGINFO")
|
417
|
+
entries[i] = entries[0]
|
418
|
+
entries[0] = ".PKGINFO"
|
419
|
+
break
|
420
|
+
end
|
421
|
+
end
|
422
|
+
|
423
|
+
# add entries to arguments.
|
424
|
+
entries.each do |entry|
|
425
|
+
unless(entry == '..' || entry == '.')
|
426
|
+
args = args << entry
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
safesystem(*args)
|
431
|
+
end
|
432
|
+
end
|
433
|
+
|
434
|
+
# APK adds a "PAX" magic string into most directory names.
|
435
|
+
# This takes an unchanged directory name and "paxifies" it.
|
436
|
+
def add_paxstring(ret)
|
437
|
+
|
438
|
+
pax_slash = ret.rindex('/')
|
439
|
+
if(pax_slash == nil)
|
440
|
+
pax_slash = 0
|
441
|
+
else
|
442
|
+
pax_slash = ret.rindex('/', pax_slash-1)
|
443
|
+
if(pax_slash == nil || pax_slash < 0)
|
444
|
+
pax_slash = 0
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
ret = ret.insert(pax_slash, "/PaxHeaders.14670/")
|
449
|
+
ret = ret.sub("//", "/")
|
450
|
+
return ret
|
451
|
+
end
|
452
|
+
|
453
|
+
# Appends null zeroes to the end of [ret] until it is divisible by [length].
|
454
|
+
# Returns the padded result.
|
455
|
+
def pad_string_to(ret, length)
|
456
|
+
|
457
|
+
until(ret.length % length == 0)
|
458
|
+
ret << "\0"
|
459
|
+
end
|
460
|
+
return ret
|
461
|
+
end
|
462
|
+
|
463
|
+
# Replaces every character between [start] and [finish] in the given [str]
|
464
|
+
# with [character].
|
465
|
+
def replace_string_range(str, start, finish, character)
|
466
|
+
|
467
|
+
for i in (start..finish)
|
468
|
+
str[i] = character
|
469
|
+
end
|
470
|
+
|
471
|
+
return str
|
472
|
+
end
|
473
|
+
|
474
|
+
# Nulls out the ownership bits of the given tar [header].
|
475
|
+
def replace_ownership_headers(header, nullify_names)
|
476
|
+
|
477
|
+
# magic
|
478
|
+
header[TAR_MAGIC_START..TAR_MAGIC_END] = "ustar\0" + "00"
|
479
|
+
|
480
|
+
# ids
|
481
|
+
header = replace_string_range(header, TAR_UID_START, TAR_UID_END, "0")
|
482
|
+
header = replace_string_range(header, TAR_GID_START, TAR_GID_END, "0")
|
483
|
+
header[TAR_GID_END] = "\0"
|
484
|
+
header[TAR_UID_END] = "\0"
|
485
|
+
|
486
|
+
# names
|
487
|
+
if(nullify_names)
|
488
|
+
header = replace_string_range(header, TAR_UNAME_START, TAR_UNAME_END, "\0")
|
489
|
+
header = replace_string_range(header, TAR_GNAME_START, TAR_GNAME_END, "\0")
|
490
|
+
|
491
|
+
# major/minor
|
492
|
+
header[TAR_MAJOR_START..TAR_MAJOR_END] = "0".rjust(8, '0')
|
493
|
+
header[TAR_MINOR_START..TAR_MINOR_END] = "0".rjust(8, '0')
|
494
|
+
header[TAR_MAJOR_END] = "\0"
|
495
|
+
header[TAR_MINOR_END] = "\0"
|
496
|
+
else
|
497
|
+
header[TAR_UNAME_START..TAR_UNAME_END] = pad_string_to("root", 32)
|
498
|
+
header[TAR_GNAME_START..TAR_GNAME_END] = pad_string_to("root", 32)
|
499
|
+
end
|
500
|
+
|
501
|
+
return header
|
502
|
+
end
|
503
|
+
|
504
|
+
def to_s(format=nil)
|
505
|
+
return super("NAME_FULLVERSION_ARCH.TYPE") if format.nil?
|
506
|
+
return super(format)
|
507
|
+
end
|
508
|
+
|
509
|
+
public(:input, :output, :architecture, :name, :prefix, :converted_from, :to_s)
|
510
|
+
end
|