112 lines
2.5 KiB
Ruby
112 lines
2.5 KiB
Ruby
|
|
#!/usr/bin/env ruby
|
||
|
|
|
||
|
|
# $Id: ruby 1708 2006-02-24 10:09:22Z ward $
|
||
|
|
# $URL$
|
||
|
|
|
||
|
|
#
|
||
|
|
# Copyright (c) 2007 Ward Wouts <ward@wouts.nl>
|
||
|
|
#
|
||
|
|
# Permission to use, copy, modify, and distribute this software for any
|
||
|
|
# purpose with or without fee is hereby granted, provided that the above
|
||
|
|
# copyright notice and this permission notice appear in all copies.
|
||
|
|
#
|
||
|
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||
|
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||
|
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||
|
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||
|
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||
|
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||
|
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||
|
|
#
|
||
|
|
|
||
|
|
require 'getoptlong'
|
||
|
|
|
||
|
|
def usage
|
||
|
|
puts <<EOT
|
||
|
|
Usage: #{$0.sub(/.*\//, "")} [options]
|
||
|
|
|
||
|
|
-h, --help Show this message
|
||
|
|
-s, --source <source> Source file
|
||
|
|
-t, --target <target> Target file; default "<source>.trimmed"
|
||
|
|
|
||
|
|
EOT
|
||
|
|
exit 1
|
||
|
|
end
|
||
|
|
|
||
|
|
def cmdline
|
||
|
|
options = Hash.new
|
||
|
|
begin
|
||
|
|
opts = GetoptLong.new(
|
||
|
|
[ "-s", "--source", GetoptLong::REQUIRED_ARGUMENT ],
|
||
|
|
[ "-t", "--target", GetoptLong::REQUIRED_ARGUMENT ],
|
||
|
|
[ "-h", "--help", GetoptLong::NO_ARGUMENT ]
|
||
|
|
)
|
||
|
|
opts.quiet=true
|
||
|
|
|
||
|
|
opts.each do |opt, arg|
|
||
|
|
options[opt] = arg
|
||
|
|
end
|
||
|
|
|
||
|
|
rescue
|
||
|
|
print "#{$!}\n"
|
||
|
|
usage
|
||
|
|
end
|
||
|
|
if options["-h"]
|
||
|
|
usage
|
||
|
|
elsif options["-s"].nil?
|
||
|
|
usage
|
||
|
|
end
|
||
|
|
if options["-t"].nil?
|
||
|
|
options["-t"] = "#{options["-s"]}.trimmed"
|
||
|
|
end
|
||
|
|
return options
|
||
|
|
end
|
||
|
|
|
||
|
|
options = cmdline
|
||
|
|
|
||
|
|
if FileTest.exists?(options["-t"])
|
||
|
|
puts "Target #{options["-t"]} already exists, not overwriting"
|
||
|
|
exit 1
|
||
|
|
end
|
||
|
|
|
||
|
|
if ! FileTest.readable?(options["-s"])
|
||
|
|
puts "Source #{options["-s"]} not readable, exiting"
|
||
|
|
exit 1
|
||
|
|
end
|
||
|
|
|
||
|
|
size = File.stat(options["-s"]).size
|
||
|
|
trimpos = size
|
||
|
|
|
||
|
|
# read last 1KB, check if all bytes are all te same
|
||
|
|
sourcefile = File.new(options["-s"], "r")
|
||
|
|
sourcefile.seek(-1024, IO::SEEK_END)
|
||
|
|
block = sourcefile.read(1024)
|
||
|
|
byte = block[0]
|
||
|
|
block.each_byte{ |b|
|
||
|
|
if b != byte
|
||
|
|
puts "Last 1KB of #{source} doesn't appear to be filler"
|
||
|
|
exit 1
|
||
|
|
end
|
||
|
|
}
|
||
|
|
|
||
|
|
# scan backwards in blocks of 1KB until a byte differs
|
||
|
|
while true do
|
||
|
|
sourcefile.seek(-2048, IO::SEEK_CUR)
|
||
|
|
block2 = sourcefile.read(1024)
|
||
|
|
if block2 != block
|
||
|
|
trimpos = sourcefile.pos
|
||
|
|
break
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
puts "Trimming to #{trimpos} bytes"
|
||
|
|
|
||
|
|
# back to the beginning
|
||
|
|
sourcefile.seek(0, IO::SEEK_SET)
|
||
|
|
|
||
|
|
# open target
|
||
|
|
targetfile = File.new(options["-t"], "w")
|
||
|
|
while sourcefile.pos < trimpos do
|
||
|
|
targetfile.write(sourcefile.read(1024))
|
||
|
|
end
|