
| Current Path : /var/www/web-klick.de/dsh/91_archiv/fuer_backup/bin/ |
Linux ift1.ift-informatik.de 5.4.0-216-generic #236-Ubuntu SMP Fri Apr 11 19:53:21 UTC 2025 x86_64 |
| Current File : /var/www/web-klick.de/dsh/91_archiv/fuer_backup/bin/cddb.pl |
#!/usr/bin/perl -I.
#
# CDDB - Read the CDDB entry for an audio CD in your drive
#
# This module/script gets the CDDB info for an audio cd. You need
# LINUX, a cdrom drive and an active internet connection in order
# to do that.
#
# (c) 2004 Armin Obersteiner <armin@xos.net>
#
# LICENSE
#
# This library is released under the same conditions as Perl, that
# is, either of the following:
#
# a) the GNU General Public License Version 2 as published by the
# Free Software Foundation,
#
# b) the Artistic License.
#
#use CDDB_get qw( get_cddb get_discids );
@INC = ("/akt/appserv","/usr/local/bin/utility",@main::INC);
use Data::Dumper;
use Getopt::Std;
use strict;
my %option = ();
getopts("oghdtsi:SfDlOFc:H:CIRGP", \%option);
if($option{h}) {
print "$0: gets CDDB info of a CD\n";
print " no argument - gets CDDB info of CD in your drive\n";
print " -c device (other than default device)\n";
print " -o offline mode - just stores CD info\n";
print " -d output in xmcd format\n";
print " -s save in xmcd format\n";
print " -i db. one of: mysql, pg, oracle, sqlite\n";
print " -O overwrite file or db\n";
print " -t output toc\n";
print " -l output lame command\n";
print " -f http mode (e.g. through firewalls)\n";
print " -F some stateful firewalls/http proxies need additional newlines\n";
print " -g get CDDB info for stored CDs\n";
print " -I non interactive mode\n";
print " -H CDDB hostname\n";
print " -C use local cache\n";
print " -R readonly cache\n";
print " -G cache has not the diskid as filenames (much slower)\n";
print " -P cache path (default: /tmp/xmcd)\n";
print " -D put CDDB_get in debug mode\n";
exit;
}
my %config;
my $diskid;
my $total;
my $toc;
my $savedir="/tmp/cddb";
my $xmcddir="/tmp/xmcd";
if($option{C}) {
# use CDDB_cache qw( get_cddb get_discids );
require CDDB_cache;
CDDB_cache->import( qw( get_cddb get_discids ) );
$CDDB_cache::debug=1 if($option{D});
$CDDB_cache::readonly=1 if($option{R});
$CDDB_cache::grep=1 if($option{G});
$CDDB_cache::dir="/tmp/xmcd"; # default
# $CDDB_cache::dir="/opt/kde2/share/apps/kscd/cddb";
$CDDB_cache::dir=$option{P} if($option{P});
} else {
# use CDDB_get qw( get_cddb get_discids );
require CDDB_get;
CDDB_get->import( qw( get_cddb get_discids ) );
}
$CDDB_get::debug=1 if($option{D});
# following variables just need to be declared if different from defaults
# defaults are listed below (cdrom default is os specific)
# $config{CDDB_HOST}="freedb.freedb.org"; # set cddb host
if($option{H}) {
$config{CDDB_HOST}=$option{H};
}
# $config{CDDB_PORT}=8880; # set cddb port
# $config{CDDB_MODE}="cddb"; # set cddb mode: cddb or http, this is switched with -f
# $config{CD_DEVICE}="/dev/cdrom"; # set cd device
# $config{HELLO_ID} ="root nowhere.com fastrip 0.77"; # hello string: username hostname clientname version
# $config{PROTO_VERSION} = 5; # cddb protokol version
# get proxy settings for cddb mode
$config{HTTP_PROXY}=$ENV{http_proxy} if $ENV{http_proxy}; # maybe wanna use a proxy ?
$config{CDDB_MODE}="http" if($option{f});
if($option{F}) {
$config{CDDB_MODE}="http";
$config{FW}=1;
}
$config{CD_DEVICE}=$option{c} if $option{c};
# user interaction welcome?
$config{input}=1; # 1: ask user if more than one possibility
# 0: no user interaction
$config{multi}=0; # 1: do not ask user and get all of them
# 0: just the first one
$config{input}=0 if($option{I});
my %db;
if($option{i}) {
require DBI;
$db{table_cds} = "cds";
$db{table_tracks} = "tracks";
# not needed for sqlite
$db{host} = "localhost";
$db{port} = "3306";
# not needed for oracle/sqlite
$db{name} = "mp3-test";
# just for oracle
$db{sid} = "xxx";
$db{home} = "xxx";
# just for sqlite
$db{file} = "xxx";
# not needed for sqlite
$db{user} = "root";
$db{passwd} = "xxx";
if($option{i} eq "mysql") {
$db{connect} = sub { "dbi:mysql:database=$db{name};host=$db{host};port=$db{port}", $db{user}, $db{passwd} };
} elsif($option{i} eq "pg") {
$db{connect} = sub { "dbi:Pg:dbname=$db{dbname};host=$db{host};port=$db{port}", $db{user}, $db{passwd} };
} elsif($option{i} eq "oracle") {
$db{connect} = sub { "dbi:Oracle:host=$db{host};sid=$db{sid};port=$db{port}", $db{user}, $db{passwd} };
$ENV{ORACLE_HOME} = $db{home};
} elsif($option{i} eq "sqlite") {
$db{connect} = sub { "dbi:SQLite:dbname=$db{file}","","" };
} else {
die "unkown database: $option{i}";
}
}
if($option{o}) {
my $ids=get_discids($config{CD_DEVICE});
unless(-e $savedir) {
mkdir $savedir,0755 or die "cannot create $savedir";
}
open OUT,">$savedir/$ids->[0]\_$$" or die "cannot open outfile";
print OUT Data::Dumper->Dump($ids,["diskid","total","toc"]);
close OUT;
print STDERR "saved in: $savedir/$ids->[0]\_$$\n";
exit;
}
if($option{g}) {
print STDERR "retrieving stored cds ...\n";
opendir(DIR, $savedir) or die "cannot opendir $savedir";
while (defined(my $file = readdir(DIR))) {
next if($file =~ /^\./);
print "\n";
my $in=`/bin/cat $savedir/$file`;
my $exit = $? >> 8;
if($exit>0) {
die "error reading file";
}
unless($in=~ m/^\$diskid\s+=\s+('\d+'|\d+);\s+ # $diskid
\$total\s+=\s+('\d+'|\d+);\s+ # $total
\$toc\s+=\s+\[\s+ # $toc
(\{\s+
('(frame|frames|min|sec|data)'\s+=\>\s+('\d+'|\d+)(,|)\s+){5}
\}(,|)\s+)+
\];\s+$/xs) {
print "not a save file: $savedir/$file\n";
next;
}
eval $in;
if($@) {
print "not a save file (eval error): $savedir/$file\n";
next;
}
my %cd=get_cddb(\%config,[$diskid,$total,$toc]);
unless(defined $cd{title}) {
print "no cddb entry found: $savedir/$file\n";
}
unlink "$savedir/$file";
next unless defined $cd{title};
if($option{d} || $option{s}) {
print_xmcd(\%cd,$option{s});
} elsif($option{i}) {
insert_db(\%cd,\%db);
} elsif($option{l}) {
print_lame(\%cd);
} else {
print_cd(\%cd);
}
}
closedir(DIR);
exit;
}
# get it on
unless($config{multi}) {
my %cd;
# for those who don't like 'die' in modules ;-)
eval {
%cd = get_cddb(\%config);
};
if ($@) {
print "fatal error: $!\n";
exit;
}
print Dumper(\%cd) if $option{D};
unless(defined $cd{title}) {
die "no cddb entry found";
}
# do somthing with the results
if($option{d} || $option{s}) {
print_xmcd(\%cd,$option{s});
} elsif($option{i}) {
insert_db(\%cd,\%db);
} elsif($option{l}) {
print_lame(\%cd);
} else {
print_cd(\%cd);
}
} else {
my @cd;
# for those who don't like 'die' in modules ;-)
eval {
@cd=get_cddb(\%config);
};
if ($@) {
print "fatal error: $!\n";
exit;
}
print Dumper(\@cd) if $option{D};
for my $c (@cd) {
unless(defined $c->{title}) {
die "no cddb entry found";
}
# do somthing with the results
if($option{d} || $option{s}) {
print_xmcd($c,$option{s});
} elsif($option{i}) {
insert_db($c,\%db);
} elsif($option{l}) {
print_lame($c);
print "\n";
} else {
print_cd($c);
print "\n";
}
}
}
exit;
# subroutines
sub print_cd {
my $cd=shift;
print "artist: $cd->{artist}\n";
print "title: $cd->{title}\n";
print "category: $cd->{cat}\n";
print "genre: $cd->{genre}\n" if($cd->{genre});
print "year: $cd->{year}\n" if($cd->{year});
print "cddbid: $cd->{id}\n";
print "trackno: $cd->{tno}\n";
my $n=1;
foreach my $i ( @{$cd->{track}} ) {
if($option{t}) {
my $from=$cd->{frames}[$n-1];
my $to=$cd->{frames}[$n]-1;
my $dur=$to-$from;
my $min=int($dur/75/60);
my $sec=int($dur/75)-$min*60;
my $frm=($dur-$sec*75-$min*75*60)*100/75;
my $out=sprintf "track %2d: %8d - %8d [%2d:%.2d.%.2d]: $i\n",$n,$from,$to,$min,$sec,$frm;
print "$out";
} else {
print "track $n: $i\n";
}
$n++;
}
}
sub print_xmcd {
my $cd=shift;
my $save=shift;
*OUT=*STDOUT;
if($save) {
unless(-e $xmcddir) {
mkdir $xmcddir,0755 or die "cannot create $savedir";
}
unless($option{O}) {
if(-e "$xmcddir/$cd->{id}") {
print "XMCD file exists\n";
exit;
}
}
open XMCD,">$xmcddir/$cd->{id}" or die "cannot open outfile";
*OUT=*XMCD;
}
for(@{$cd->{raw}}) {
print OUT "$_";
}
if($save) {
print STDERR "saved in: $xmcddir/$cd->{id}\n";
close OUT;
}
}
sub insert_db {
my $cd=shift;
my $db=shift;
my ($artist, $title, $category, $cddbid, $trackno) =
($cd->{artist}, $cd->{title}, $cd->{cat}, $cd->{id}, $cd->{tno});
my $sql = "SELECT cddbid FROM $db->{table_cds} WHERE CDDBID = \'$cddbid\'";
my $dbh = DBI->connect($db->{connect}->()) or die "cannot connect to db: $DBI::errstr";
my $sth = $dbh->prepare($sql);
my $r = $sth->execute or die "cannot check for cd: $DBI::errstr";
if ($r == 1) {
print "cd already in db\n";
if($option{O}) {
my $sql = "DELETE FROM $db->{table_cds} WHERE CDDBID = \'$cddbid\'";
my $sth = $dbh->prepare($sql);
my $r = $sth->execute or die "cannot delete from $db->{table_cds}: $DBI::errstr";
$sql = "DELETE FROM $db->{table_tracks} WHERE CDDBID = \'$cddbid\'";
$sth = $dbh->prepare($sql);
$r = $sth->execute or die "cannot delete from $db->{table_tracks}: $DBI::errstr";
} else {
exit;
}
}
$title =~ s/'/\\'/g;
$artist =~ s/'/\\'/g;
$category =~ s/'/\\'/g;
$sql = "INSERT INTO $db->{table_cds} (cddbid, artist, title, category, tracks) VALUES (\'$cddbid\', \'$artist\', \'$title\', \'$category\' , \'$trackno\')";
$sth = $dbh->prepare($sql);
$r = $sth->execute or die "failed to insert cd: $DBI::errstr";
my $n=1;
print "titel: $title\n";
print "artist: $artist\n";
print "category: $category\n\n";
for my $t ( @{$cd->{track}} ) {
$t =~ s/'/\\'/g;
my $dur=($cd->{frames}[$n]-1-$cd->{frames}[$n-1])/75;
my $hour=int($dur/3600);
my $min=int($dur/60-$hour*60);
my $sec=$dur-$hour*3600-$min*60;
my $fr=substr(sprintf("%5.2f",$sec-int($sec)),2,3);
my $time=sprintf "%.2d:%.2d:%.2d%s",$hour,$min,int($sec),$fr;
print "track $n: $t [$time]\n";
my $sql = "INSERT INTO $db->{table_tracks} (cddbid, title, trackno, time)
VALUES (\'$cddbid\',\'$t\', \'$n\', \'$time\')";
my $sth = $dbh->prepare($sql);
my $r = $sth->execute or die "failed to insert track $n: $DBI::errstr";
$n++;
}
$dbh->disconnect();
}
sub print_lame {
my $cd=shift;
print_cd($cd);
print "\n";
my $n=1;
for my $i ( @{$cd->{track}} ) {
$i =~ s/"/'/g;
print 'lame --tl "'.$cd->{title}.'" --ta "'.$cd->{artist}.'" --tt "'.$i.'" ';
printf "audio_%02d.wav ",$n;
$i =~ s/[^\S]|['"\/]/_/g;
$i =~ s/_+-_+/-/g;
print " $i.mp3\n";
$n++;
}
}
#
# CDDB - Read the CDDB entry for an audio CD in your drive
#
# This module/script gets the CDDB info for an audio cd. You need
# LINUX, a cdrom drive and an active internet connection in order
# to do that.
#
# (c) 2004 Armin Obersteiner <armin@xos.net>
#
# LICENSE
#
# This library is released under the same conditions as Perl, that
# is, either of the following:
#
# a) the GNU General Public License Version 2 as published by the
# Free Software Foundation,
#
# b) the Artistic License.
#
package CDDB_get;
use Config;
use strict;
use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $debug);
require Exporter;
@ISA = qw(Exporter AutoLoader);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
@EXPORT_OK = qw(
get_cddb
get_discids
);
$VERSION = '2.27';
use Fcntl;
use IO::Socket;
use Data::Dumper qw(Dumper);
#$debug=1;
# setup for linux, solaris x86, solaris spark
# you freebsd guys give me input
print STDERR "cddb: checking for os ... " if $debug;
my $os=`uname -s`;
my $machine=`uname -m`;
chomp $os;
chomp $machine;
print STDERR "$os ($machine) " if $debug;
# cdrom IOCTL magic (from c headers)
# linux x86 is default
# /usr/include/linux/cdrom.h
my $CDROMREADTOCHDR=0x5305;
my $CDROMREADTOCENTRY=0x5306;
my $CDROM_MSF=0x02;
# default config
my $CDDB_HOST = "freedb.freedb.org";
my $CDDB_PORT = 8880;
my $CDDB_MODE = "cddb";
my $CD_DEVICE = "/dev/cdrom";
my $HELLO_ID = "root nowhere.com fastrip 0.77";
my $PROTO_VERSION = 5;
# endian check
my $BIG_ENDIAN = unpack("h*", pack("s", 1)) =~ /01/;
if($BIG_ENDIAN) {
print STDERR "[big endian] " if $debug;
} else {
print STDERR "[little endian] " if $debug;
}
# 64bit pointer check
my $BITS_64 = $Config{ptrsize} == 8 ? 1 : 0;
if($BITS_64) {
print STDERR "[64 bit]\n" if $debug;
} else {
print STDERR "[32 bit]\n" if $debug;
}
if($os eq "SunOS") {
# /usr/include/sys/cdio.h
$CDROMREADTOCHDR=0x49b; # 1179
$CDROMREADTOCENTRY=0x49c; # 1180
if(-e "/vol/dev/aliases/cdrom0") {
$CD_DEVICE="/vol/dev/aliases/cdrom0";
} else {
if($machine =~ /^sun/) {
# on sparc and old suns
$CD_DEVICE="/dev/rdsk/c0t6d0s0";
} else {
# on intel
$CD_DEVICE="/dev/rdsk/c1t0d0p0";
}
}
} elsif($os =~ /BSD/i) { # works for netbsd, infos for other bsds welcome
# /usr/include/sys/cdio.h
$CDROMREADTOCHDR=0x40046304;
$CDROMREADTOCENTRY=0xc0086305;
if($BITS_64) {
$CDROMREADTOCENTRY=0xc0106305;
}
$CD_DEVICE="/dev/cd0a";
if($os eq "OpenBSD") {
$CD_DEVICE="/dev/cd0c";
}
}
sub read_toc {
my $device=shift;
my $tochdr=chr(0) x 16;
sysopen (CD,$device, O_RDONLY | O_NONBLOCK) or die "cannot open cdrom [$!] [$device]";
ioctl(CD, $CDROMREADTOCHDR, $tochdr) or die "cannot read toc [$!] [$device]";
my ($start,$end);
if($os =~ /BSD/) {
($start,$end)=unpack "CC",(substr $tochdr,2,2);
} else {
($start,$end)=unpack "CC",$tochdr;
}
print STDERR "start track: $start, end track: $end\n" if $debug;
my @tracks=();
for (my $i=$start; $i<=$end;$i++) {
push @tracks,$i;
}
push @tracks,0xAA;
my @r=();
my $tocentry;
my $toc="";
my $size=0;
for(@tracks) {
$toc.=" ";
$size+=8;
}
if($os =~ /BSD/) {
my $size_hi=int($size / 256);
my $size_lo=$size & 255;
if($BIG_ENDIAN) {
if($BITS_64) {
# better but just perl >= 5.8.0
# $tocentry=pack "CCCCx![P]P", $CDROM_MSF,0,$size_hi,$size_lo,$toc;
$tocentry=pack "CCCCxxxxP", $CDROM_MSF,0,$size_hi,$size_lo,$toc;
} else {
$tocentry=pack "CCCCP8l", $CDROM_MSF,0,$size_hi,$size_lo,$toc;
}
} else {
if($BITS_64) {
$tocentry=pack "CCCCxxxxP", $CDROM_MSF,0,$size_lo,$size_hi,$toc;
} else {
$tocentry=pack "CCCCP8l", $CDROM_MSF,0,$size_lo,$size_hi,$toc;
}
}
ioctl(CD, $CDROMREADTOCENTRY, $tocentry) or die "cannot read track info [$!] [$device]";
}
my $count=0;
foreach my $i (@tracks) {
my ($min,$sec,$frame);
unless($os =~ /BSD/) {
$tocentry=pack "CCC", $i,0,$CDROM_MSF;
$tocentry.=chr(0) x 16;
ioctl(CD, $CDROMREADTOCENTRY, $tocentry) or die "cannot read track $i info [$!] [$device]";
($min,$sec,$frame)=unpack "CCCC", substr($tocentry,4,4);
} else {
($min,$sec,$frame)=unpack "CCC", substr($toc,$count+5,3);
}
$count+=8;
my %cdtoc=();
$cdtoc{min}=$min;
$cdtoc{sec}=$sec;
$cdtoc{frame}=$frame;
$cdtoc{frames}=int($frame+$sec*75+$min*60*75);
my $data = unpack("C",substr($tocentry,1,1));
$cdtoc{data} = 0;
if($data & 0x40) {
$cdtoc{data} = 1;
}
push @r,\%cdtoc;
}
close(CD);
return @r;
}
sub cddb_sum {
my $n=shift;
my $ret=0;
while ($n > 0) {
$ret += ($n % 10);
$n = int $n / 10;
}
return $ret;
}
sub cddb_discid {
my $total=shift;
my $toc=shift;
my $i=0;
my $t=0;
my $n=0;
while ($i < $total) {
$n = $n + cddb_sum(($toc->[$i]->{min} * 60) + $toc->[$i]->{sec});
$i++;
}
$t = (($toc->[$total]->{min} * 60) + $toc->[$total]->{sec}) -
(($toc->[0]->{min} * 60) + $toc->[0]->{sec});
return (($n % 0xff) << 24 | $t << 8 | $total);
}
sub get_discids {
my $cd=shift;
$CD_DEVICE = $cd if (defined($cd));
my @toc=read_toc($CD_DEVICE);
my $total=$#toc;
my $id=cddb_discid($total,\@toc);
return [$id,$total,\@toc];
}
sub get_cddb {
my $config=shift;
my $diskid=shift;
my $id;
my $toc;
my $total;
my @r;
my $input = $config->{input};
my $multi = $config->{multi};
$input = 0 if $multi;
print STDERR Dumper($config) if $debug;
$CDDB_HOST = $config->{CDDB_HOST} if (defined($config->{CDDB_HOST}));
$CDDB_PORT = $config->{CDDB_PORT} if (defined($config->{CDDB_PORT}));
$CDDB_MODE = $config->{CDDB_MODE} if (defined($config->{CDDB_MODE}));
$CD_DEVICE = $config->{CD_DEVICE} if (defined($config->{CD_DEVICE}));
$HELLO_ID = $config->{HELLO_ID} if (defined($config->{HELLO_ID}));
$PROTO_VERSION = $config->{PROTO_VERSION} if (defined($config->{PROTO_VERSION}));
my $HTTP_PROXY = $config->{HTTP_PROXY} if (defined($config->{HTTP_PROXY}));
my $FW=1 if (defined($config->{FW}));
if(defined($diskid)) {
$id=$diskid->[0];
$total=$diskid->[1];
$toc=$diskid->[2];
} else {
my $diskid=get_discids($CD_DEVICE);
$id=$diskid->[0];
$total=$diskid->[1];
$toc=$diskid->[2];
}
my @list=();
my $return;
my $socket;
my $id2 = sprintf "%08x", $id;
my $query = "cddb query $id2 $total";
for (my $i=0; $i<$total ;$i++) {
$query.=" $toc->[$i]->{frames}";
}
# this was to old total calculation, does not work too well, its included if new version makes problems
# $query.=" ". int(($toc->[$total]->{frames}-$toc->[0]->{frames})/75);
$query.=" ". int(($toc->[$total]->{frames})/75);
print Dumper($toc) if $debug;
if ($CDDB_MODE eq "cddb") {
print STDERR "cddb: connecting to $CDDB_HOST:$CDDB_PORT\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$CDDB_HOST, PeerPort=>$CDDB_PORT,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $CDDB_HOST:$CDDB_PORT [$!]";
$return=<$socket>;
unless ($return =~ /^2\d\d\s+/) {
die "not welcome at cddb db";
}
print $socket "cddb hello $HELLO_ID\n";
$return=<$socket>;
print STDERR "hello return: $return" if $debug;
unless ($return =~ /^2\d\d\s+/) {
die "handshake error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
print $socket "proto $PROTO_VERSION\n";
$return=<$socket>;
print STDERR "proto return: $return" if $debug;
unless ($return =~ /^2\d\d\s+/) {
die "protokoll mismatch error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
print STDERR "cddb: sending: $query\n" if $debug;
print $socket "$query\n";
$return=<$socket>;
chomp $return;
print STDERR "cddb: result: $return\n" if $debug;
} elsif ($CDDB_MODE eq "http") {
my $query2=$query;
$query2 =~ s/ /+/g;
my $id=$HELLO_ID;
$id =~ s/ /+/g;
my $url = "/~cddb/cddb.cgi?cmd=$query2&hello=$id&proto=$PROTO_VERSION";
my $host=$CDDB_HOST;
my $port=80;
my ($user,$pass);
if($HTTP_PROXY) {
if($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(.+)\@(.+?):(.+)/) {
$user=$2;
$pass=$3;
$host=$4;
$port=$5;
} elsif($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(\d+)/) {
$host=$2;
$port=$3;
}
$url="http://$CDDB_HOST".$url." HTTP/1.0";
}
print STDERR "cddb: connecting to $host:$port\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $host:$port [$!]";
print STDERR "cddb: http send: GET $url\n" if $debug;
print $socket "GET $url\n";
if($user) {
my $cred = encode_base64("$user:$pass");
print $socket "Proxy-Authorization: Basic $cred\n";
}
print $socket "\n";
print $socket "\n" if $FW;
if($HTTP_PROXY) {
while(<$socket> =~ /^\S+/){};
}
$return=<$socket>;
chomp $return;
print STDERR "cddb: http result: $return\n" if $debug;
} else {
die "unkown mode: $CDDB_MODE for querying cddb";
}
$return =~ s/\r//g;
my ($err) = $return =~ /^(\d\d\d)\s+/;
unless ($err =~ /^2/) {
die "query error at cddb db: $CDDB_HOST:$CDDB_PORT";
}
if($err==202) {
return undef;
} elsif(($err==211) || ($err==210)) {
while(<$socket>) {
last if(/^\./);
push @list,$_;
s/\r//g;
print STDERR "unexact: $_" if $debug;
}
} elsif($err==200) {
$return =~ s/^200 //;
push @list,$return;
} else {
die "cddb: unknown: $return";
}
my @to_get;
unless($multi) {
if (@list) {
my $index;
if($input==1) {
print "This CD could be:\n\n";
my $i=1;
for(@list) {
my ($tit) = $_ =~ /^\S+\s+\S+\s+(.*)/;
print "$i: $tit\n";
$i++
}
print "\n0: none of the above\n\nChoose: ";
my $n=<STDIN>;
$index=int($n);
} else {
$index=1;
}
if ($index == 0) {
return undef;
} else {
push @to_get,$list[$index-1];
}
}
} else {
push @to_get,@list;
}
my $i=0;
for my $get (@to_get) {
#200 misc 0a01e802 Meredith Brooks / Bitch Single
my ($cat,$id,$at) = $get =~ /^(\S+?)\s+(\S+?)\s+(.*)/;
my $artist;
my $title;
if($at =~ /\//) {
($artist,$title)= $at =~ /^(.*?)\s\/\s(.*)/;
} else {
$artist=$at;
$title=$at;
}
my %cd=();
$cd{artist}=$artist;
chomp $title;
$title =~ s/\r//g;
$cd{title}=$title;
$cd{cat}=$cat;
$cd{id}=$id;
my @lines;
$query="cddb read $cat $id";
if ($CDDB_MODE eq "cddb") {
print STDERR "cddb: getting: $query\n" if $debug;
print $socket "$query\n";
while(<$socket>) {
last if(/^\./);
push @lines,$_;
}
if(@to_get-1 == $i) {
print $socket "quit\n";
close $socket;
}
} elsif ($CDDB_MODE eq "http") {
close $socket;
my $query2=$query;
$query2 =~ s/ /+/g;
my $id=$HELLO_ID;
$id =~ s/ /+/g;
my $url = "/~cddb/cddb.cgi?cmd=$query2&hello=$id&proto=$PROTO_VERSION";
my $host=$CDDB_HOST;
my $port=80;
my ($user,$pass);
if($HTTP_PROXY) {
if($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(.+)\@(.+?):(.+)/) {
$user=$2;
$pass=$3;
$host=$4;
$port=$5;
} elsif($HTTP_PROXY =~ /^(http:\/\/|)(.+?):(\d+)/) {
$host=$2;
$port=$3;
}
$url="http://$CDDB_HOST".$url." HTTP/1.0";
}
print STDERR "cddb: connecting to $host:$port\n" if $debug;
$socket=IO::Socket::INET->new(PeerAddr=>$host, PeerPort=>$port,
Proto=>"tcp",Type=>SOCK_STREAM) or die "cannot connect to cddb db: $host:$port [$!]";
print STDERR "cddb: http send: GET $url\n" if $debug;
print $socket "GET $url\n";
if($user) {
my $cred = encode_base64("$user:$pass");
print $socket "Proxy-Authorization: Basic $cred\n";
}
print $socket "\n";
print $socket "\n" if $FW;
if($HTTP_PROXY) {
while(<$socket> =~ /^\S+/){};
}
while(<$socket>) {
last if(/^\./);
push @lines,$_;
}
close $socket;
} else {
die "unkown mode: $CDDB_MODE for querying cddb";
}
# xmcd
#
# Track frame offsets:
# 150
# ...
# 210627
#
# Disc length: 2952 seconds
#
# Revision: 1
# Submitted via: xmcd 2.0
#
for(@lines) {
last if(/^\./);
next if(/^\d\d\d/);
push @{$cd{raw}},$_;
#TTITLE0=Bitch (Edit)
if(/^TTITLE(\d+)\=\s*(.*)/) {
my $t= $2;
chop $t;
$cd{frames}[$1]=$toc->[$1]->{frames};
$cd{data}[$1]=$toc->[$1]->{data};
unless (defined $cd{track}[$1]) {
$cd{track}[$1]=$t;
} else {
$cd{track}[$1]=$cd{track}[$1].$t;
}
} elsif(/^DYEAR=\s*(\d+)/) {
$cd{'year'} = $1;
} elsif(/^DGENRE=\s*(\S+.*)/) {
my $t = $1;
chop $t;
$cd{'genre'} = $t;
} elsif(/^\#\s+Revision:\s+(\d+)/) {
$cd{'revision'} = $1;
}
}
$cd{tno}=$#{$cd{track}}+1;
$cd{frames}[$cd{tno}]=$toc->[$cd{tno}]->{frames};
return %cd unless($multi);
push @r,\%cd;
$i++;
}
return @r;
}
1;
__END__
# Below is the stub of documentation for your module. You better edit it!
=head1 NAME
CDDB - Read the CDDB entry for an audio CD in your drive
=head1 SYNOPSIS
use CDDB_get qw( get_cddb );
my %config;
# following variables just need to be declared if different from defaults
$config{CDDB_HOST}="freedb.freedb.org"; # set cddb host
$config{CDDB_PORT}=8880; # set cddb port
$config{CDDB_MODE}="cddb"; # set cddb mode: cddb or http
$config{CD_DEVICE}="/dev/cdrom"; # set cd device
# user interaction welcome?
$config{input}=1; # 1: ask user if more than one possibility
# 0: no user interaction
# get it on
my %cd=get_cddb(\%config);
unless(defined $cd{title}) {
die "no cddb entry found";
}
# do somthing with the results
print "artist: $cd{artist}\n";
print "title: $cd{title}\n";
print "category: $cd{cat}\n";
print "cddbid: $cd{id}\n";
print "trackno: $cd{tno}\n";
my $n=1;
foreach my $i ( @{$cd{track}} ) {
print "track $n: $i\n";
$n++;
}
=head1 DESCRIPTION
This module/script gets the CDDB info for an audio cd. You need
LINUX, SUNOS or *BSD, a cdrom drive and an active internet connection
in order to do that.
=head1 INSTALLATION
Run "perl Makefile.pl" as usual. ("make", "make install" next)
=head1 LICENSE & DISCLAIMER
This library is released under the same conditions as Perl, that
is, either of the following:
a) the GNU General Public License Version 2 as published by the
Free Software Foundation,
b) the Artistic License.
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 either
the GNU General Public License or the Artistic License for more details.
You should have received a copy of the Artistic License with this
Kit, in the file named "Artistic". If not, I'll be glad to provide one.
You should also have received a copy of the GNU General Public License
along with this program, in the file names "Copying"; if not, write to
the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
MA 02111-1307, USA.
If you use this library in a commercial enterprise, you are invited,
but not required, to pay what you feel is a reasonable fee to the
author, who can be contacted at armin@xos.net
=head1 AUTHOR & COPYRIGHT
(c) 2003 Armin Obersteiner <armin(at)xos(dot)net>
=head1 SEE ALSO
perl(1), Linux: F</usr/include/linux/cdrom.h>,
Solaris, *BSD: F</usr/include/sys/cdio.h>.
=cut