#!/usr/bin/env ruby # $Id: ruby 1708 2006-02-24 10:09:22Z ward $ # $URL$ # # Copyright (c) 2007 Ward Wouts # # 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 < Source file -t, --target Target file; default ".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