#!/usr/bin/perl #------------------------------------------------------------------------------- # burn - Written 08/10/2001 by Kelly Cash kelly@the-clearing.org # # Purpose: A little menuing utility for burning CDs. Data, MP3s, ISO, Audio, etc. # Written for: Solaris, Linux, FreeBSD. It might run under perl on Windows, # but no doubt syntax of locations and devices would need to be # modified. So why bother? Use a REAL operating system instead! # # Arguments: None. # Sub scripts: None. # Called by: None. # Routines needed: cdda2wav, cdrecord, cdrdao, mkisofs These can be obtained at: # http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html # # Notes: * Must be root (when running Unix and variants) to write to the CD Burner. # * Modify customizable variables below to reflect your preferences and devices. # * My system configuration has a CDROM and CD-RW on a SCSI bus, and an # IDE CDROM. Your devices are probably different, so the structure of # some of the options may need modification (to say the least). # * Do a "cdrecord -scanbus" to find drives # * The "debug" variable is 0 by default. Positive value prints extra info. # # Planned enhancements: Addition of use of cdrdao- "CD Record Disk At Once." # This will facilitate burning an audio CD without any # silence between the tracks. Good for live albums. # The "-pad" option in cdrecord doesn't do this. # # Revision History: # Who When What # KCash 08/10/01 Initial Implementation # KCash 10/01/02 Added functionality for reading/writing from same device # KCash 10/02/02 Implemented subroutines to clean up code # KCash 10/04/02 Added documentation # KCash 10/11/02 Added code: burning ISO images # KCash 10/23/02 Added code: specifying burn speed for audio CDs # KCash 11/06/02 Added code: removing ISO images after burn # KCash 01/28/03 Added code: prompt whether to query for ripping okay # KCash 01/28/03 Added code: prompt to re-run the utility (for multiple burns) #------------------------------------------------------------------------------- # ---- Beginning of user customizable variables -------------------------------- $dev_burn = 5; # SCSI device number of CD burner $dev_read = 6; # SCSI device number of CD reader $tools_dir = "/usr/bin"; # Where to find mkisofs, cdda2wav, cdrecord $iso_img = "/usr/home/kelly/diskimage.isofs"; # What file to store the ISO image in $burn_dir = "/usr/home/kelly/Burn_Directory"; # Directory of stuff to burn to CD $def_speed = 20; # Default (max) write speed of burner $debug = 0; # Level of debug output. 0 is default # ---- End of user customizable variables -------------------------------------- # Figure out who we are. If not root, bail. die "This utility must be run as root.\n" if (index(`id`,"uid=0(root)") < 0); sub set_pad { # Prompts user for whether to zero-pad a file on the CD-R or not. printf "Zero-pad the file(s) (y/N)? "; chop($pad = ); if ($pad eq "y") { $pad = "-pad"; } else { $pad = "-nopad"; } } sub clean_tmps { # Prompts user whether to delete or keep stuff just ripped (for 2nd copy) printf "\nDelete the files ripped (y/N)? "; chop($cleanup = ); if ($cleanup eq "y") { system("rm -r tmpwavcd"); } } sub audio_copy { # Routine for reading from a CD drive and writing to a CD (with intermediate disk) ($dev_src, $dev_dest) = @_; printf "Src device=%d Dest device=%d\n", $dev_src, $dev_dest if ($debug > 0); # Make a temporary directory to load the stuff from the source CD system("mkdir tmpwavcd"); chdir tmpwavcd; &get_speed; # Pull off the tracks of the CD into the temp directory system("$tools_dir/cdda2wav -D 0,$dev_src,0 -O cdr -B -v 127"); # Sometimes the drive will have an error when copying data from the CD to disk. # In these cases, we must be able to start ripping again at the track the had # the problem. if ($rquery eq "y") { printf "Did all files rip off the CD properly (Y/n)? "; chop($ripped = ); while ($ripped eq "n") { printf "Resume ripping at which track? "; chop($res_track = ); system("$tools_dir/cdda2wav -D 0,$dev_src,0 -O cdr -B -t $res_track -v 127"); printf "Did all files rip off the CD properly (y,n)? "; chop($ripped = ); } } if ($dev_src == 5) { # If reading from burner, prompt to change disks printf "Remove source CD from the burner, insert a blank, and hit \\: "; chop($trash = ); } system("$tools_dir/cdrecord dev=0,$dev_dest,0 -speed=$def_speed -v -audio $eject *.cdr"); chdir (".."); &clean_tmps; } sub get_speed { # Routine for setting burn speed printf "Enter burn speed (default=%d): ", $def_speed; chop ($speed = ); if ($speed eq "") { $speed = $def_speed } printf "Speed=%d Def_speed=%d\n", $speed, $def_speed if ($debug > 0); } sub remove_file { # Routine for prompting for file deletion ($rfile) = @_; printf "rfile = %s\n", $rfile if ($debug > 0); printf "Remove ISO image %s (y/N)? : ", $rfile; chop ($kill = ); system("rm $rfile") if ($kill eq "y"); } printf "Eject after burn (y/N)? "; chop ($ej_cmd = ); if ($ej_cmd eq "y") { $eject = "-eject"; } else { $eject = " "; } printf "Query for whether all files ripped off source okay (y/N)? "; chop ($rquery = ); $rerun = "y"; while ($rerun ne "n") { printf "\nData/MP3/ISO operations:\n"; printf "1. Copy data/mp3 CD in 52x CDROM drive\n"; printf "2. Copy data/mp3 items in Burn Directory\n"; printf "3. Re-Burn another disk from Burn Directory\n"; printf "4. Write an ISO image to burner\n"; printf "\nMusic operations:\n"; printf "5. Copy music CD in Plextor SCSI CDROM drive\n"; printf "6. Copy music CD in burner TO burner (faster)\n"; printf "7. Re-Copy music ripped from operation 2 or 3 above\n"; printf "8. Copy music items in Burn Directory\n"; printf "\n Enter operation: "; chop ($operation = ); # There's no case or switch statement in perl, so I'll fake it, ugly though it may be. if ($operation == 1) { # Copies a data CD from 52x CDROM to burner &set_pad; printf "Put disks in drives, hit return: "; chop ($trash = ); # The syntax of the mount command will probably have to be modifed for your system. system("mount -o ro /dev/cdrom /cdrom"); system("$tools_dir/mkisofs -R /cdrom | cdrecord -v -speed=$def_speed $pad $eject -dev=0,$dev_burn,0 -v -"); system("umount /cdrom"); } elsif ($operation == 2) { # Burns a data (incl. mp3s) CD that's readable by Unix, Linux, Windows system ("rm $iso_img"); # Make a listing file that has the long filenames. Some operating systems # won't recognize REALLY long names. system ("ls -RC1 $burn_dir > $burn_dir/AA_INDEX.TXT"); &set_pad; printf "Enter volume label: "; chop ($volid = ); system("$tools_dir/mkisofs -L -l -J -r -T -V $volid -o $iso_img $burn_dir"); system("$tools_dir/cdrecord -v -speed=$def_speed $pad $eject -dev=0,$dev_burn,0 $iso_img"); } elsif ($operation == 3) { # Re-burns a data (incl. mp3s) CD from the ISO image made above &set_pad; system("$tools_dir/cdrecord -v -speed=$def_speed $pad $eject -dev=0,$dev_burn,0 $iso_img"); } elsif ($operation == 4) { # Dumps an ISO image onto the burner &set_pad; printf "\nISO images in this directory:\n"; system("ls -a *.iso"); printf "\nEnter ISO image or pathname to burn: "; chop ($iso = ); &get_speed; system("$tools_dir/cdrecord -v -speed=$speed dev=0,$dev_burn,0 $pad $eject $iso"); &remove_file($iso); } elsif ($operation == 5) { # Copies a music CD from the SCSI CDROM to a directory then to the burner &audio_copy($dev_read,$dev_burn); } elsif ($operation == 6) { # Copies a music CD from the SCSI CD-RW to a directory then back &audio_copy($dev_burn,$dev_burn); } elsif ($operation == 7) { # Re-Burns another CD from the previous rip operation above chdir tmpwavcd; &get_speed; system("$tools_dir/cdrecord dev=0,$dev_burn,0 -v -speed=$def_speed -audio $eject *.cdr"); chdir (".."); &clean_tmps; } elsif ($operation == 8) { # Burns a CD from the music items in the Burn_Directory chdir ("$burn_dir"); &get_speed; system("$tools_dir/cdrecord -v -speed=$def_speed dev=0,$dev_burn,0 $eject -audio *.cdr"); } printf "Burn another disk (Y/n)? "; chop ($rerun = ); }