package CDiso; use Cwd; # Some package level globals $VERSION="1.0.0.2"; sub new { my ($self, $root)=@_; $self={ _root=>undef, _files=>undef, _size=>0, _mkisofs_path=> 'mkisofs', _volume_label=> time(), #default to time }; bless $self, 'CDiso'; if(defined($root) && -d $root) { $self->{_root} = $root; } return $self; } sub version { my ($self) = @_; return $VERSION; } sub size { my ($self) = @_; return $self->{_size}; } sub mkisofsPath { my ($self, $path) = @_; $self->{_mkisofs_path} = $path if(defined($path) && -e $path); return $self->{_mkisofs_path}; } sub volumeLabel { my ($self, $label) = @_; $self->{_volume_label} = $label if defined($label); return $self->{_volume_label}; } sub root { my ($self, $root) = @_; $self->{_root} = $root if(defined($root) && -d $root); return $self->{_root}; } sub addFiles { my ($self, @files) = @_; my @fileinfo; if(!defined($self->{_root})) { error("root directory not set"); } foreach $file(@files) { if(-e $file) { if(!($file=~m/^$self->{_root}/)) { warn("file $file is not in a sub-directory of root dir $self->{_root}"); warn("NOT adding file $file"); } else { if(!defined($self->{_files}{$file})) { $self->{_files}{$file}=1; @fileinfo = stat($file); $self->{_size} += $fileinfo[7]; # 7 = file size in bytes } } } else { warn("file does not exist: $file"); } } } sub printFiles { my ($self) = @_; foreach $file(keys %{$self->{_files}}) { print "$file\n"; } } sub makeISO { my($self, $imageName) = @_; if(!defined($imageName)) { error("makeISO called, but no image name provided.\n"); } my $tmpdir = $self->getTempDir(); my $excludeFile = $tmpdir. "/excludeList" . time() . ".txt"; open OUT, ">$excludeFile" or error("Unable to open exclude file $excludeFile"); my $cwd = cwd(); #save this off chdir($self->{_root}) || error("Unable to cd to $self->{_root}"); $self->scanDir($self->{_root}); chdir($cwd); # restore cwd close OUT; my @cmd = ($self->{_mkisofs_path}, "-r", # rock ridge "-J", # joliet "-joliet-long", "-o", $imageName, "-V", $self->{_volume_label}, "-v", "-exclude-list", $excludeFile); foreach $path(@paths_to_exclude) { push(@cmd, '-x'); push(@cmd, $path); } push(@cmd, $self->{_root}); print STDERR ("+ @cmd\n"); system (@cmd); unlink($excludeFile) if -e $excludeFile; } sub scanDir { my ($self, $dir) = @_; my $cwd = cwd(); chdir($dir) || error("Unable to cd to $dir"); my @files = <*>; my @dirs; my $return_value = 0; foreach $file(@files) { if(-d $file) { push(@dirs, $file); } else { if(!defined($self->{_files}{"$dir/$file"})) { print OUT "$dir/$file\n"; } else { $return_value = 1; } } } foreach $directory(@dirs) { $return_value |= $self->scanDir("$dir/$directory"); } if($return_value == 0) { push(@paths_to_exclude, $dir); } return $return_value; } sub getTempDir { my ($self) = @_; if(defined($ENV{'TEMP'}) && -d $ENV{'TEMP'}) { return $ENV{'TEMP'}; } if(defined($ENV{'TMP'}) && -d $ENV{'TMP'}) { return $ENV{'TMP'}; } if(defined($ENV{'TEMPDIR'}) && -d $ENV{'TEMPDIR'}) { return $ENV{'TEMPDIR'}; } # as a last resort, try /tmp if(-d '/tmp') { return '/tmp'; } error("Unable to determine a temporary directory."); } sub error { my ($msg) = @_; print "ERROR: $msg\n"; exit(1); } sub warn { my ($msg) = @_; print "WARNING: $msg\n"; } =head1 NAME B - A package that wraps the mkisofs interface to simplify the process of making CD disk images =head1 SYNOPSIS use CDiso; my $iso = new CDiso('/tmp/test'); $iso->mkisofsPath('/path/to/mkisofs'); # files that you want to add $files[0]='/tmp/test/a.txt'; $files[1]='/tmp/test/b.txt'; $files[2]='/tmp/test/c.txt'; $files[3]='/tmp/test/level1/level1_a.txt'; # add the files $iso->addFiles(@files); #make the iso $iso->makeISO("/path/to/example.iso"); =head1 DESCRIPTION This module provides a front end for the mkisofs program. =head1 METHODS =head2 addFiles() $iso->addFiles(@array_of_files_to_add); $iso->addFiles($individual_file_to_add); Adds the file(s) specified in the arguments to the function to the files that will be included when making the disk image =head2 makeISO() $iso->makeISO('/tmp/output.iso'); This is the method where all the magic happens. This method constructs a disk image by making a call to the mkisofs program. The files included on the disk image are only those files that were explicitly added via the addFiles method. All other files below the root directory are excluded. This method writes a temporary file to a temp directory, but removes that file once the .iso has been built. =head2 mkisofsPath() $iso->mkisofsPath('/path/to/mkisofs'); Sets the path to the mkisofs executable. =head2 new() $iso = new CDiso($root); Creates a new CDiso object. $root is an optional argument. $root is the path to the root of the files that you will be adding to the final .iso. If you don't set root via this constructor, you can set it by calling the I method. =head2 printFiles() $iso->printFiles Prints a list of all the files that have been added to the CDiso object. This is mainly for debugging purposes. =head2 root() $iso->root($root); Sets the root of the files that will be included in the .iso image. =head2 size() $iso->size(); Returns the size in bytes of all files that have been added to the iso. =head2 version() $iso->version(); Returns the version of the CDiso package. =head2 volumeLabel() $iso->volumeLabel($label); Sets the Volume label for the disk image to $label. If you do not set the volume label, it defaults to the system time (# of seconds since the epoch). =head1 AUTHOR Jason Hancock, C<< >> =head1 BUGS Please report any bugs or feature requests to C. =head1 TODO There are a few things I would like to add to this package in the future. One would be to check the sizes of each file that is added to the disk image to make sure we don't exceed the 650MB or 700MB limits. If you want something added, email me a request at (jsnby AT hotmail DOT com). =head1 COPYRIGHT & LICENSE Copyright (C) 2007 Jason Hancock (jsnby AT hotmail DOT com) http://jsnby.is-a-geek.com This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA =cut 1;