#!/usr/bin/perl -w use strict; use vars qw(); use Fatal qw(open close ioctl); ### try to load some cdrom constants if( ! eval { require "linux/cdrom.ph" } ){ my $error; if( $@ =~ /^(Can\'t locate .+? in \@INC)/ ){ $error = $1 ."\n You may need to run h2ph.\n"; }else{ $error = $@; } print $error; print "Continuing with hard coded constants...\n"; ### copy from linux/cdrom.ph eval 'sub CDROMREADTOCHDR () {0x5305;}' unless defined(&CDROMREADTOCHDR); eval 'sub CDROMREADTOCENTRY () {0x5306;}' unless defined(&CDROMREADTOCENTRY); eval 'sub CDROM_MSF () {0x02;}' unless defined(&CDROM_MSF); } ### open the cdrom device print "Opening cd device...\n"; my $device = "/dev/hdc"; # not portable...yet open(_DEV,"<$device"); ### read the toc range print "Reading toc header...\n"; my $str = ''; ioctl(_DEV, CDROMREADTOCHDR(), $str); my $track0 = ord( substr($str,0,1) ); my $trackn = ord( substr($str,1,1) ); print "Track range: [$track0][$trackn]\n"; ### read the entries print "Reading toc entries...\n"; for(my $i = $track0; $i <= $trackn; $i ++){ my $track = $i; my $format = CDROM_MSF(); my $struct = "CC4C4CCCCiC"; my $str = pack($struct,$track,0,0,$format); ioctl(_DEV, CDROMREADTOCENTRY(), $str); my($_track,$adr,$ctrl,$_format, $min,$sec,$frame, $lba, $datamode) = unpack($struct,$str); print "$_track $adr $_format $min $sec $frame\n"; } print "Done\n"; __END__ # Sample calling code and structs # struct cdrom_tocentry tocentry; # tocentry.cdte_track = i; # tocentry.cdte_format = CDROM_MSF; # ioctl(drive, CDROMREADTOCENTRY, &tocentry); # # struct cdrom_msf0 # { # __u8 minute; # __u8 second; # __u8 frame; # }; # # /* Address in either MSF or logical format */ # union cdrom_addr # { # struct cdrom_msf0 msf; # int lba; # }; # # struct cdrom_tocentry # { # __u8 cdte_track; # __u8 cdte_adr :4; # __u8 cdte_ctrl :4; # __u8 cdte_format; # union cdrom_addr cdte_addr; # __u8 cdte_datamode; # };