152 lines
3.8 KiB
C
152 lines
3.8 KiB
C
/* --------------------------------------------------------------------------
|
|
|
|
MusicBrainz -- The Internet music metadatabase
|
|
|
|
Copyright (C) 2006 Matthias Friedrich
|
|
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
--------------------------------------------------------------------------- */
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
|
|
#include "discid/discid_private.h"
|
|
#include "unix.h"
|
|
|
|
|
|
int mb_disc_unix_exists(const char *device) {
|
|
int fd;
|
|
fd = open(device, O_RDONLY | O_NONBLOCK);
|
|
if (fd < 0) {
|
|
/* we only check for existance, access should fail later on */
|
|
if (errno == ENOENT) {
|
|
return 0;
|
|
} else {
|
|
return 1;
|
|
}
|
|
} else {
|
|
close(fd);
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
char *mb_disc_unix_find_device(char *candidates[], int num_candidates) {
|
|
int i;
|
|
|
|
for (i = 0; i < num_candidates; i++) {
|
|
if (mb_disc_unix_exists(candidates[i])) {
|
|
return candidates[i];
|
|
}
|
|
}
|
|
/* use the first name for the error message later on */
|
|
return candidates[0];
|
|
}
|
|
|
|
int mb_disc_unix_open(mb_disc_private *disc, const char *device) {
|
|
int fd;
|
|
|
|
fd = open(device, O_RDONLY | O_NONBLOCK);
|
|
if (fd < 0) {
|
|
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
|
|
"cannot open device `%s'", device);
|
|
}
|
|
/* fd < 0 check needs to be made by caller */
|
|
return fd;
|
|
}
|
|
|
|
int mb_disc_unix_read_toc(int fd, mb_disc_private *disc, mb_disc_toc *toc) {
|
|
int i;
|
|
|
|
/* Find the numbers of the first track (usually 1) and the last track. */
|
|
if ( !mb_disc_unix_read_toc_header(fd, toc) ) {
|
|
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
|
|
"cannot read table of contents");
|
|
return 0;
|
|
}
|
|
|
|
/* basic error checking */
|
|
if ( toc->last_track_num == 0 ) {
|
|
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
|
|
"this disc has no tracks");
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Read the TOC entry for every track.
|
|
*/
|
|
for (i = toc->first_track_num; i <= toc->last_track_num; i++) {
|
|
if ( !mb_disc_unix_read_toc_entry(fd, i, &toc->tracks[i]) ) {
|
|
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
|
|
"cannot read TOC entry for track %d", i);
|
|
return 0;
|
|
}
|
|
}
|
|
if ( !mb_disc_unix_read_toc_entry(fd, 0xAA, &toc->tracks[0]) ) {
|
|
snprintf(disc->error_msg, MB_ERROR_MSG_LENGTH,
|
|
"cannot read TOC entry for lead-out");
|
|
return 0;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
int mb_disc_unix_read(mb_disc_private *disc, const char *device,
|
|
unsigned int features) {
|
|
mb_disc_toc toc;
|
|
int fd;
|
|
int i;
|
|
|
|
fd = mb_disc_unix_open(disc, device);
|
|
if (fd < 0)
|
|
return 0;
|
|
|
|
|
|
if ( !mb_disc_unix_read_toc(fd, disc, &toc) ) {
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
if ( !mb_disc_load_toc(disc, &toc) ) {
|
|
close(fd);
|
|
return 0;
|
|
}
|
|
|
|
/* Read in the media catalog number */
|
|
if (features & DISCID_FEATURE_MCN
|
|
&& mb_disc_has_feature_unportable(DISCID_FEATURE_MCN)) {
|
|
mb_disc_unix_read_mcn(fd, disc);
|
|
}
|
|
|
|
/* Read the ISRC for the track */
|
|
if (features & DISCID_FEATURE_ISRC
|
|
&& mb_disc_has_feature_unportable(DISCID_FEATURE_ISRC)) {
|
|
for (i = disc->first_track_num; i <= disc->last_track_num; i++) {
|
|
mb_disc_unix_read_isrc(fd, disc, i);
|
|
}
|
|
}
|
|
|
|
close(fd);
|
|
|
|
return 1;
|
|
}
|
|
/* EOF */
|