#!/usr/bin/env ruby # $Id: iso2.rb,v 1.7 2006/12/16 03:44:48 rocky Exp $ # A program to show using iso9660 to extract a file # from an ISO-9660 image. # # If a single argument is given, it is used as the ISO 9660 image to # use in the extraction. Otherwise a compiled in default ISO 9660 # image name (that comes with the libcdio distribution) will be used. # Copyright (C) 2006 Rocky Bernstein # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA mypath = File.dirname(__FILE__) if(File::exists?(mypath + "/../lib/cdio.rb")) $: << File.dirname(__FILE__) + '/../lib' $: << File.dirname(__FILE__) + '/../ext/cdio' $: << File.dirname(__FILE__) + '/../ext/iso9660' else require 'rubygems' require_gem "rbcdio" end require "iso9660" # The default CD image if none given cd_image_path = "../data" cd_image_fname = cd_image_path + "/isofs-m1.cue" # File to extract if none given. iso9660_path="/" local_filename="COPYING" if ARGV.length() > 1 cd_image_fname = ARGV[0] if ARGV.length() > 2 local_filename = ARGV[1] if ARGV.length() > 3 puts "\nusage: %s [CD-ROM-or-image [filename]]\nExtracts filename from CD-ROM-or-image." % $0 exit(1) end end end begin cd = ISO9660::FS::new(cd_image_fname) rescue puts "Sorry, couldn't open %s as a CD image." % cd_image_fname exit(1) end statbuf = cd.stat(local_filename, false) if not statbuf puts "Could not get ISO-9660 file information for file %s in %s" % [local_filename, cd_image_name] cd.close() exit(2) end o = open(local_filename, "w", 0664) if not o puts "Can't open %s for writing" % local_filename end # Copy the blocks from the ISO-9660 filesystem to the local filesystem. blocks = (statbuf['size'].to_f / Rubycdio::ISO_BLOCKSIZE).ceil() for i in 0 .. blocks - 1 lsn = statbuf['lsn'] + i size, buf = cd.read_data_blocks(lsn) if size < 0 puts "Error reading ISO 9660 file %s at LSN %d" % [ local_filename, lsn] exit(4) end o.write(buf) end o.close() # Make sure the file size has the exact same byte size. Without the # truncate below, the file will a multiple of ISO_BLOCKSIZE. f = File.new(local_filename, "r+") f.truncate(statbuf['size']) f.close() puts "Extraction of file '%s' from %s successful." % [ local_filename, cd_image_fname] cd.close() exit(0)