pkgsrc/misc/mkcue/files/mb_dragonfly.cpp

160 lines
3.7 KiB
C++

/* --------------------------------------------------------------------------
MusicBrainz -- The Internet music metadatabase
Copyright (C) 2000 Robert Kaye
Copyright (C) 1999 Marc E E van Woerkom
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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 the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----------------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <netinet/in.h>
#include "mb.h"
#include "diskid.h"
#include "config.h"
MUSICBRAINZ_DEVICE DEFAULT_DEVICE = "/dev/cd0";
int ReadTOCHeader(int fd,
int& first,
int& last)
{
struct ioc_toc_header th;
int ret = ioctl(fd,
CDIOREADTOCHEADER,
&th);
if (!ret)
{
first = th.starting_track;
last = th.ending_track;
}
return ret;
}
int ReadTOCEntry(int fd,
int track,
int& lba)
{
struct ioc_read_toc_entry te;
te.starting_track = (u_char) track;
te.address_format = CD_LBA_FORMAT; // experiment and cdio.h say
// lbas are given in network order!
struct cd_toc_entry cte;
te.data = &cte;
te.data_len = sizeof(cd_toc_entry);
int ret = ioctl(fd,
CDIOREADTOCENTRYS,
&te);
if (!ret) {
assert(te.address_format == CD_LBA_FORMAT);
lba = ntohl(te.data->addr.lba); // network to host order (long)
}
return ret;
}
bool DiskId::ReadTOC(MUSICBRAINZ_DEVICE device,
MUSICBRAINZ_CDINFO& cdinfo)
{
int fd;
int first;
int last;
int lba;
int i;
if (device == NULL)
{
device = DEFAULT_DEVICE;
}
fd = open(device, O_RDONLY);
if (fd < 0)
{
char err[256];
sprintf(err, "Cannot open '%s'", device);
ReportError(err);
return false;
}
// Initialize cdinfo to all zeroes.
memset(&cdinfo, 0, sizeof(MUSICBRAINZ_CDINFO));
// Find the number of the first track (usually 1) and the last track.
if (ReadTOCHeader(fd, first, last))
{
ReportError("Cannot read table of contents.");
close(fd);
return false;
}
// Do some basic error checking.
if (last==0)
{
ReportError("This disk has no tracks.");
close(fd);
return false;
}
// Now, for every track, find out the block address where it starts.
for (i = first; i <= last; i++)
{
ReadTOCEntry(fd, i, lba);
cdinfo.FrameOffset[i] = lba + 150;
}
// Get the logical block address (lba) for the end of the audio data.
// The "LEADOUT" track is the track beyond the final audio track
// so we're looking for the block address of the LEADOUT track.
int CDROM_LEADOUT = last + 1;
ReadTOCEntry(fd, CDROM_LEADOUT, lba);
cdinfo.FrameOffset[0] = lba + 150;
cdinfo.FirstTrack = first;
cdinfo.LastTrack = last;
close(fd);
return true;
}