quickdev16/scripts/zip2raw.rb
2009-10-19 11:52:20 +02:00

147 lines
3.5 KiB
Ruby

use_file_names = true
include_file_names = false
loop do
if ARGF.read(2) != "PK"
if ARGF.eof?
exit
end
warn "Input is not a zip file"
exit 1
end
if !(ARGF.read(2) == "\003\004") # file header
exit
end
version = ARGF.read(2).unpack("v").first
# i should use this to sort out some incompatible file formats....
bitflag = ( ARGF.read(2).unpack("v").first)
use_data_descriptor = bitflag[3] == 1
# should check for things that are unsupported for sure....
c_method = ARGF.read(2).unpack("v").first
if c_method != 8
warn "Unknown compression method"
end
if c_method > 255
warn "Unsupported compression method"
exit 1
end
last_mod_time = ARGF.read(2) # unsupported until i know how to convert dos to unix time
last_mod_date = ARGF.read(2) # unsupported until i know how to convert dos to unix time
crc_32 = ARGF.read(4).unpack("V").first
size = ARGF.read(4).unpack("V").first
if use_data_descriptor
size = :auto
end
uncompressed_size = ARGF.read(4).unpack("V").first
file_name_length = ARGF.read(2).unpack("v").first
extra_field_length = ARGF.read(2).unpack("v").first
file_name = ARGF.read(file_name_length)
ARGF.read(extra_field_length) # extra field.. no use (yet?)
file_name2 = file_name
if use_file_names
outfile = nil
while !outfile
if !(file_name2 =~ /\//)
used_filename = file_name2
outfile = File.open("#{file_name2}.deflate","w")
end
file_name2 = "zip2gz_file%05i" % rand(100000)
end
else
outfile = STDOUT
end
#generate gz header
#outfile.print "\x1f\x8b"
#outfile.putc c_method
flags = 0
if include_file_names && !file_name.empty?
flags |= 0b1000
end
#outfile.print flags.chr
#outfile.print [0].pack("V") # no time conversion (yet)
#outfile.print 2.chr # maybe copy first 3 bits of the zip extra flags? default to maximum compression
#outfile.print 255.chr # this is stored in the central directory... (same for comments) we don't parse this...
#if include_file_names && !file_name.empty?
# outfile.print file_name.tr("\x00"," ")+"\x00"
#end
if size != :auto
blocks = size / 0x100
rest = size & 0xFF
blocks.times do
outfile.print ARGF.read(0x100)
end
outfile.print ARGF.read(rest)
else
size = -14
buffer = ""
loop do
buffer << ARGF.getc
size += 1
if buffer.size > 14
outfile.putc buffer[0]
buffer[0,1] = ""
end
if buffer.size == 14
crc, c_size, u_size, magic_number = buffer.unpack("VVVa2")
if c_size == size && c_size <= u_size && magic_number == "PK"
break
ARGF.ungetc "K"
ARGF.ungetc "P"
uncompressed_size = u_size
crc_32 = crc
end
end
end
end
#outfile.print [crc_32, uncompressed_size ].pack("VV")
if file_name.empty?
warn "Successfully wrote file crc32:%08X length:%i to %s" % [crc_32, size, (outfile == STDOUT ? "stdout" : "#{used_filename}.deflate")]
else
warn "Successfully wrote file \"%s\" crc32:%08X length:%i to %s" % [file_name, crc_32, size, (outfile == STDOUT ? "stdout" : "#{used_filename}.deflate")]
end
if use_file_names
outfile.close
end
end