Index: MANIFEST =================================================================== --- MANIFEST (.../vendor/current) (revision 9) +++ MANIFEST (.../Net-FreeDB) (revision 9) @@ -6,6 +6,7 @@ README TODO lib/discid.h +lib/freebsd.h lib/linux.h lib/myaspi32.h lib/scsidefs.h Index: lib/freebsd.h =================================================================== --- lib/freebsd.h (.../vendor/current) (revision 0) +++ lib/freebsd.h (.../Net-FreeDB) (revision 9) @@ -0,0 +1,160 @@ + /********************************************* +NAME: freebsd.h +FUNCTION: FreeBSD based cddb id generation code +ORIGINALLY CREATED BY: David Shultz +ORIGINALLY CREATED ON: 08/03/2001 +ADAPTED BY: Peter Pentchev +ADAPTED ON: 09/28/2005 +*********************************************/ +#ifndef FREEBSD_H +#define FREEBSD_H + +struct discdata { + unsigned long discid; + int num_of_trks; + int track_offsets[100]; + int seconds; +}; + +/* + * The following has been blatantly stolen from FreeBSD 5.4's + * cdcontrol(8) utility. + */ + +int msf; +struct cd_toc_entry toc_buffer[100]; + +int read_toc_entrys (int fd, int len) +{ + struct ioc_read_toc_entry t; + + t.address_format = msf ? CD_MSF_FORMAT : CD_LBA_FORMAT; + t.starting_track = 0; + t.data_len = len; + t.data = toc_buffer; + + return (ioctl (fd, CDIOREADTOCENTRYS, (char *) &t)); +} + +void lba2msf (unsigned long lba, u_char *m, u_char *s, u_char *f) +{ + lba += 150; /* block start offset */ + lba &= 0xffffff; /* negative lbas use only 24 bits */ + *m = lba / (60 * 75); + lba %= (60 * 75); + *s = lba / 75; + *f = lba % 75; +} + +/* + * dbprog_sum + * Convert an integer to its text string representation, and + * compute its checksum. Used by dbprog_discid to derive the + * disc ID. + * + * Args: + * n - The integer value. + * + * Return: + * The integer checksum. + */ +static int +dbprog_sum(int n) +{ + char buf[12], + *p; + int ret = 0; + + /* For backward compatibility this algorithm must not change */ + sprintf(buf, "%u", n); + for (p = buf; *p != '\0'; p++) + ret += (*p - '0'); + + return(ret); +} + +/* + * dbprog_discid + * Compute a magic disc ID based on the number of tracks, + * the length of each track, and a checksum of the string + * that represents the offset of each track. + * + * Args: + * s - Pointer to the curstat_t structure. + * + * Return: + * The integer disc ID. + */ +int +dbprog_discid(int fd, struct discdata *d) +{ + struct ioc_toc_header h; + int rc; + int i, ntr, + t = 0, + n = 0; + long block; + u_char m, s, f; + + rc = ioctl (fd, CDIOREADTOCHEADER, &h); + if (rc < 0) + return (0); + ntr = h.ending_track - h.starting_track + 1; + i = msf; + msf = 1; + rc = read_toc_entrys (fd, (ntr + 1) * sizeof (struct cd_toc_entry)); + msf = i; + if (rc < 0) + return (0); + d->num_of_trks = ntr; + + /* For backward compatibility this algorithm must not change */ + d->track_offsets[0] = 150; + for (i = 0; i < ntr; i++) { +#define TC_FR(a) toc_buffer[a].addr.msf.frame +#define TC_MM(a) toc_buffer[a].addr.msf.minute +#define TC_SS(a) toc_buffer[a].addr.msf.second + n += dbprog_sum((TC_MM(i) * 60) + TC_SS(i)); + + t += ((TC_MM(i+1) * 60) + TC_SS(i+1)) - + ((TC_MM(i) * 60) + TC_SS(i)); + + d->track_offsets[i + 1] = TC_FR(i + 1) + TC_MM(i + 1) * 60 * 75 + + TC_SS(i+1)*75; + fprintf(stderr, "i %d mm %d ss %d fr %d ofs %ld\n", i + 1, TC_MM(i + 1), TC_SS(i + 1), TC_FR(i + 1), d->track_offsets[i]); + } + + d->discid = (n % 0xff) << 24 | t << 8 | ntr; + /* + block = ntohl(toc_buffer[ntr - 1].addr.lba); + d->seconds = ((block + 150) & 0xfffff) / 75; + */ + d->seconds = TC_SS(ntr) + TC_MM(ntr) * 60; + fprintf(stderr, "block is %ld, seconds are %ld\n", block, d->seconds); + return (d->discid); +} + +struct discdata +get_disc_id(const char *dev) +{ + int fd; + struct discdata d; + + fd = open(dev, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + memset(&d, 0, sizeof(d)); + return (d); + } + dbprog_discid(fd, &d); + close(fd); + return (d); +} + +#endif //FREEBSD_H + + + + + + + Index: lib/discid.h =================================================================== --- lib/discid.h (.../vendor/current) (revision 9) +++ lib/discid.h (.../Net-FreeDB) (revision 9) @@ -37,6 +37,11 @@ #include "linux.h" #endif //__linux__ +#ifdef __FreeBSD__ +#include +#include "freebsd.h" +#endif // __FreeBSD__ + #ifdef WIN32 #include "win32.h" #endif //WIN32 Index: Makefile.PL =================================================================== --- Makefile.PL (.../vendor/current) (revision 9) +++ Makefile.PL (.../Net-FreeDB) (revision 9) @@ -3,11 +3,15 @@ # the contents of the Makefile that is written. if ($^O =~ /linux/) { print "OS: $^O, copying XS file: "; - system("cp FreeDB.xs.linux FreeDB.xs"); + system("cp FreeDB.xs.linux FreeDB.xs") && die "Copying failed\n"; print "1 file copied\n"; +} elsif ($^O =~ /freebsd/) { + print "OS: $^O, copying XS file: "; + system("cp FreeDB.xs.linux FreeDB.xs") && die "Copying failed\n"; + print "1 file copied\n"; } elsif ($^O =~ /MSWin32/) { print "OS: $^O, copying XS file:"; - system("copy FreeDB.xs.win32 FreeDB.xs"); + system("copy FreeDB.xs.win32 FreeDB.xs") && die "Copying failed\n"; } else { print "Unable to determine OS, Exiting\n"; exit(0); @@ -22,7 +26,7 @@ return '' if($path =~ m:/(RCS|CVS|SCCS)/: || $path =~ m:[~%]$: || - $path =~ m:\.(orig|rej|nfs)$: + $path =~ m:\.(orig|rej|nfs|h)$: ); $path; } @@ -81,4 +85,5 @@ 'INC' => '-Ilib', # e.g., '-I/usr/include/other' # Un-comment this if you add C files to link with later: # 'OBJECT' => '$(O_FILES)', # link all the C files too + 'clean' => { 'FILES' => 'FreeDB.xs' }, ); Index: test.pl =================================================================== --- test.pl (.../vendor/current) (revision 9) +++ test.pl (.../Net-FreeDB) (revision 9) @@ -17,7 +17,7 @@ # its man page ( perldoc Test ) for help writing this test script. ######################### -ok($cddb = new Net::FreeDB()); +ok($cddb = new Net::FreeDB('USER' => 'win32usr')); ######################### ok($cddb->read('newage', '940a070c')); @@ -38,6 +38,8 @@ my $id; if ($^O =~ /MSWin32/) { $id = $cddb->getdiscid(0); +} elsif ($^O =~ /freebsd/) { + $id = $cddb->getdiscid('/dev/acd0'); } else { $id = $cddb->getdiscid('/dev/cdrom'); } @@ -47,6 +49,8 @@ $id = undef; if ($^O =~ /MSWin32/) { $id = Net::FreeDB::getdiscid(0); +} elsif ($^O =~ /freebsd/) { + $id = Net::FreeDB::getdiscid('/dev/acd0'); } else { $id = Net::FreeDB::getdiscid('/dev/cdrom'); } @@ -56,6 +60,8 @@ $id = undef; if ($^O =~ /MSWin32/) { $id = Net::FreeDB::getdiscdata(0); +} elsif ($^O =~ /freebsd/) { + $id = Net::FreeDB::getdiscdata('/dev/acd0'); } else { $id = Net::FreeDB::getdiscdata('/dev/cdrom'); }