#!/usr/bin/perl -w # # cdstat -- show the current status of the CD in the drive verbosely # # $dotat: scripts/cdstat,v 1.23 2003/05/12 11:43:24 fanf2 Exp $ use strict; use IO::Socket; my $debug; if (@ARGV == 1 and $ARGV[0] =~ /^-(d+)$/) { $debug = length $1; } else { $debug = 0; } my $CDINFO = "$ENV{HOME}/.cdinfo"; sub debug (@) { print STDERR @_ if $debug; } debug "-- debugging level $debug\n"; exit if $debug > 3; my $cddb; sub cddbnew () { $cddb = new IO::Socket::INET (PeerAddr => 'freedb.freedb.org', PeerPort => 888) or die "$0: socket: $!\n"; $cddb->autoflush; } sub cddbrecv () { my $line = $cddb->getline; $line =~ s/\r//; debug "<- ", $line; return $line; } sub cddbsend ($) { my $line = shift; debug "-> $line\n"; print $cddb "$line\n"; } sub cddbchk () { my $line = cddbrecv; $line =~ /^2/ or die "$0: bad server response: $line"; return $line; } sub cddbcmd ($) { cddbsend shift; return cddbchk; } sub cddblines () { my @lines; my $line; while ($line = cddbrecv) { last if $line =~ /^\.\s+$/; push @lines, $line; } return @lines; } sub getcdinfo () { my @info = `cdcontrol info`; debug map "** $_", @info; @info = @info[3..$#info]; my @block = map { s/^\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+.*/ sprintf "%3s %08s %08s ", $1, $2, $3/se; $4 + 150; } @info; my $length = int ($block[-1] / 75); my $tracks = $#block; pop @block; pop @info; cddbnew; cddbchk; cddbcmd "cddb hello fanf dotat.at cdstat 1"; my $cdid = cddbcmd "discid $tracks @block $length"; $cdid =~ s/.* is (\w+).*/$1/s; my $line = cddbcmd "cddb query $cdid $tracks @block $length"; die "$0: unknown CD\n" if $line =~ /^202/; my $genre; if ($line =~ /^200 (\w+)/) { $genre = $1; } elsif ($line =~ /^211/) { my @line = cddblines or die "$0: no CDs in list\n"; if ($line[0] =~ /^(\w+) (\w+) /) { $genre = $1; $cdid = $2; } } die "$0: unknown server response: $line" unless defined $genre; cddbcmd "cddb read $genre $cdid"; my $title; for my $line (cddblines) { $title = $1 if $line =~ m/^DTITLE=(.*)/s; $info[$1] .= $2 if $line =~ m/^TTITLE(\d+)=([\S ]*)\s*$/s; } cddbcmd "quit"; return $title, map "$_\n", @info; } my $cdid = `cdcontrol cdid`; debug "** $cdid"; $cdid =~ s/^CDID=(\w+)\s+/$1/s or die "$0: unknown CDID: $cdid"; my $cdinfo = "$CDINFO/$cdid"; my @info; if (-f $cdinfo) { debug "!! locally cached\n"; open CDINFO, "< $cdinfo" or die "$0: open < $cdinfo: $!\n"; @info = ; close CDINFO; } elsif ($debug < 2) { @info = getcdinfo; mkdir $CDINFO, 0777 unless -d $CDINFO; open CDINFO, "> $cdinfo" or die "$0: open > $cdinfo: $!\n"; print CDINFO @info; close CDINFO or die "$0: writing $cdinfo: $!\n"; } else { @info = getcdinfo; } my $tracks = $#info; my $status = `cdcontrol status audio`; debug "** $status"; $status =~ /^[^<]*<([^>]*)>[^=]*= ([-0-9]+)[^=]*= ([-0-9:.]+)$/ or die "$0: unknown status: $status"; my $current_status = $1; my $current_track = $2; my $current_position = $3; $info[$current_track] =~ s/^ />/; print @info; print "$current_status at $current_position in track $current_track of $tracks\n";