Add routines which allow cdio object to be opened before cdda_open.

common_interface.h: data_bigendianp() is now public (in cdio/cdda.h)
This commit is contained in:
rocky
2005-01-22 03:45:18 +00:00
parent 33ae20b89d
commit 1062cf3c74
3 changed files with 96 additions and 61 deletions

View File

@@ -1,5 +1,5 @@
/* /*
$Id: common_interface.c,v 1.8 2005/01/14 01:36:11 rocky Exp $ $Id: common_interface.c,v 1.9 2005/01/22 03:45:18 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998, 2002 Monty monty@xiph.org Copyright (C) 1998, 2002 Monty monty@xiph.org
@@ -31,15 +31,20 @@
#include "utils.h" #include "utils.h"
#include "smallft.h" #include "smallft.h"
/*! Determine endian-ness of the CD-drive based on reading data from /*! Determine Endian-ness of the CD-drive based on reading data from
it. it. Some drives return audio data Big Endian while some (most)
return data Little Endian. Drives known to return data bigendian are
SCSI drives from Kodak, Ricoh, HP, Philips, Plasmon, Grundig
CDR100IPW, and Mitsumi CD-R. ATAPI and MMC drives are little endian.
rocky: As someone who didn't write the code, I have to say this is nothing rocky: As someone who didn't write the code, I have to say this is
less than brilliant. An FFT is done bigendian and little endian and the nothing less than brilliant. An FFT is done both ways and the the
the transform is looked at to see which has data in the FFT (or audible) transform is looked at to see which has data in the FFT (or audible)
portion. (Or so that's how I understand it.) portion. (Or so that's how I understand it.)
*/
@return 1 if big-endian, 0 if little-endian, -1 if we couldn't
figure things out or some error.
*/
int int
data_bigendianp(cdrom_drive_t *d) data_bigendianp(cdrom_drive_t *d)
{ {
@@ -149,17 +154,17 @@ data_bigendianp(cdrom_drive_t *d)
d->enable_cdda(d,0); d->enable_cdda(d,0);
/* How did we vote? Be potentially noisy */ /* How did we vote? Be potentially noisy */
if(lsb_votes>msb_votes){ if (lsb_votes>msb_votes) {
char buffer[256]; char buffer[256];
cdmessage(d,"\n\tData appears to be coming back little endian.\n"); cdmessage(d,"\n\tData appears to be coming back Little Endian.\n");
sprintf(buffer,"\tcertainty: %d%%\n",(int) sprintf(buffer,"\tcertainty: %d%%\n",(int)
(100.*lsb_votes/(lsb_votes+msb_votes)+.5)); (100.*lsb_votes/(lsb_votes+msb_votes)+.5));
cdmessage(d,buffer); cdmessage(d,buffer);
return(0); return(0);
}else{ } else {
if(msb_votes>lsb_votes){ if(msb_votes>lsb_votes){
char buffer[256]; char buffer[256];
cdmessage(d,"\n\tData appears to be coming back big endian.\n"); cdmessage(d,"\n\tData appears to be coming back Big Endian.\n");
sprintf(buffer,"\tcertainty: %d%%\n",(int) sprintf(buffer,"\tcertainty: %d%%\n",(int)
(100.*msb_votes/(lsb_votes+msb_votes)+.5)); (100.*msb_votes/(lsb_votes+msb_votes)+.5));
cdmessage(d,buffer); cdmessage(d,buffer);

View File

@@ -1,5 +1,5 @@
/* /*
$Id: common_interface.h,v 1.4 2005/01/09 12:32:19 rocky Exp $ $Id: common_interface.h,v 1.5 2005/01/22 03:45:19 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu Copyright (C) 1998 Monty xiphmont@mit.edu
@@ -34,16 +34,6 @@ extern int ioctl_ping_cdrom(int fd);
extern char *atapi_drive_info(int fd); extern char *atapi_drive_info(int fd);
/*! Determine endian-ness of the CD-drive based on reading data from
it.
rocky: As someone who didn't write the code, I have to say this is nothing
less than brilliant. An FFT is done bigendian and little endian and the
the transform is looked at to see which has data in the FFT (or audible)
portion. (Or so that's how I understand it.)
*/
extern int data_bigendianp(cdrom_drive_t *d);
/*! Here we fix up a couple of things that will never happen. yeah, /*! Here we fix up a couple of things that will never happen. yeah,
right. right.

View File

@@ -1,5 +1,5 @@
/* /*
$Id: scan_devices.c,v 1.14 2005/01/19 17:24:58 rocky Exp $ $Id: scan_devices.c,v 1.15 2005/01/22 03:45:19 rocky Exp $
Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com> Copyright (C) 2004, 2005 Rocky Bernstein <rocky@panix.com>
Copyright (C) 1998 Monty xiphmont@mit.edu Copyright (C) 1998 Monty xiphmont@mit.edu
@@ -69,11 +69,15 @@ const char *cdrom_devices[]={
"/dev/gscd", "/dev/gscd",
"/dev/optcd",NULL}; "/dev/optcd",NULL};
static cdrom_drive_t *
cdda_identify_device_cdio(CdIo_t *p_cdio, const char *psz_device,
int messagedest, char **ppsz_messages);
/* Functions here look for a cdrom drive; full init of a drive type /* Functions here look for a cdrom drive; full init of a drive type
happens in interface.c */ happens in interface.c */
cdrom_drive_t * cdrom_drive_t *
cdda_find_a_cdrom(int messagedest, char **messages){ cdda_find_a_cdrom(int messagedest, char **ppsz_messages){
/* Brute force... */ /* Brute force... */
int i=0; int i=0;
@@ -92,27 +96,27 @@ cdda_find_a_cdrom(int messagedest, char **messages){
/* number, then letter */ /* number, then letter */
buffer[pos-(cdrom_devices[i])]=j+48; buffer[pos-(cdrom_devices[i])]=j+48;
if((d=cdda_identify(buffer,messagedest,messages))) if((d=cdda_identify(buffer, messagedest, ppsz_messages)))
return(d); return(d);
idmessage(messagedest,messages,"",NULL); idmessage(messagedest, ppsz_messages, "", NULL);
buffer[pos-(cdrom_devices[i])]=j+97; buffer[pos-(cdrom_devices[i])]=j+97;
if((d=cdda_identify(buffer,messagedest,messages))) if((d=cdda_identify(buffer, messagedest, ppsz_messages)))
return(d); return(d);
idmessage(messagedest,messages,"",NULL); idmessage(messagedest, ppsz_messages, "", NULL);
} }
}else{ }else{
/* Name. Go for it. */ /* Name. Go for it. */
if((d=cdda_identify(cdrom_devices[i],messagedest,messages))) if((d=cdda_identify(cdrom_devices[i], messagedest, ppsz_messages)))
return(d); return(d);
idmessage(messagedest,messages,"",NULL); idmessage(messagedest, ppsz_messages, "", NULL);
} }
i++; i++;
} }
{ {
struct passwd *temp; struct passwd *temp;
temp=getpwuid(geteuid()); temp=getpwuid(geteuid());
idmessage(messagedest,messages, idmessage(messagedest, ppsz_messages,
"\n\nNo cdrom drives accessible to %s found.\n", "\n\nNo cdrom drives accessible to %s found.\n",
temp->pw_name); temp->pw_name);
} }
@@ -120,60 +124,71 @@ cdda_find_a_cdrom(int messagedest, char **messages){
} }
cdrom_drive_t * cdrom_drive_t *
cdda_identify(const char *device, int messagedest,char **messages) cdda_identify(const char *psz_device, int messagedest,char **ppsz_messages)
{ {
cdrom_drive_t *d=NULL; cdrom_drive_t *d=NULL;
idmessage(messagedest,messages,"Checking %s for cdrom...",device);
d=cdda_identify_cooked(device,messagedest,messages); if (psz_device)
idmessage(messagedest, ppsz_messages, "Checking %s for cdrom...",
psz_device);
else
idmessage(messagedest, ppsz_messages, "Checking for cdrom...", NULL );
d=cdda_identify_cooked(psz_device, messagedest, ppsz_messages);
return(d); return(d);
} }
cdrom_drive_t *
cdda_identify_cdio(CdIo_t *p_cdio, int messagedest, char **ppsz_messages)
{
if (!p_cdio) return NULL;
{
const char *psz_device = cdio_get_arg(p_cdio, "source");
idmessage(messagedest, ppsz_messages, "Checking %s for cdrom...",
psz_device);
return cdda_identify_device_cdio(p_cdio, psz_device, messagedest,
ppsz_messages);
}
}
static char * static char *
test_resolve_symlink(const char *file,int messagedest,char **messages) test_resolve_symlink(const char *file, int messagedest, char **ppsz_messages)
{ {
char resolved[PATH_MAX]; char resolved[PATH_MAX];
struct stat st; struct stat st;
if(lstat(file,&st)){ if (lstat(file,&st)){
idperror(messagedest,messages,"\t\tCould not stat %s",file); idperror(messagedest, ppsz_messages, "\t\tCould not stat %s",file);
return(NULL); return(NULL);
} }
if(realpath(file,resolved)) if (realpath(file,resolved))
return(strdup(resolved)); return(strdup(resolved));
idperror(messagedest,messages,"\t\tCould not resolve symlink %s",file); idperror(messagedest, ppsz_messages, "\t\tCould not resolve symlink %s",
file);
return(NULL); return(NULL);
} }
cdrom_drive_t * static cdrom_drive_t *
cdda_identify_cooked(const char *dev, int messagedest, char **messages) cdda_identify_device_cdio(CdIo_t *p_cdio, const char *psz_device,
int messagedest, char **ppsz_messages)
{ {
cdrom_drive_t *d=NULL; cdrom_drive_t *d=NULL;
int drive_type = 0; int drive_type = 0;
char *description=NULL; char *description=NULL;
char *device = NULL;
CdIo_t *p_cdio = NULL;
#ifdef HAVE_LINUX_MAJOR_H #ifdef HAVE_LINUX_MAJOR_H
struct stat st; struct stat st;
#endif #endif
if (dev) {
device = test_resolve_symlink(dev,messagedest,messages);
if ( !device ) device = strdup(dev);
}
p_cdio = cdio_open(device, DRIVER_UNKNOWN);
if (!p_cdio) { if (!p_cdio) {
idperror(messagedest,messages,"\t\tUnable to open %s", dev); idperror(messagedest, ppsz_messages, "\t\tUnable to open %s", psz_device);
if (device) free(device);
return NULL; return NULL;
} }
#ifdef HAVE_LINUX_MAJOR_H #ifdef HAVE_LINUX_MAJOR_H
if ( 0 == stat(device, &st) ) { if ( 0 == stat(psz_device, &st) ) {
if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) { if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
drive_type=(int)(st.st_rdev>>8); drive_type=(int)(st.st_rdev>>8);
switch (drive_type) { switch (drive_type) {
@@ -223,15 +238,15 @@ cdda_identify_cooked(const char *dev, int messagedest, char **messages)
case SCSI_CDROM_MAJOR: case SCSI_CDROM_MAJOR:
case SCSI_GENERIC_MAJOR: case SCSI_GENERIC_MAJOR:
/* Nope nope nope */ /* Nope nope nope */
idmessage(messagedest,messages,"\t\t%s is not a cooked ioctl CDROM.", idmessage(messagedest, ppsz_messages,
device); "\t\t%s is not a cooked ioctl CDROM.",
free(device); psz_device);
return(NULL); return(NULL);
default: default:
/* What the hell is this? */ /* What the hell is this? */
idmessage(messagedest,messages,"\t\t%s is not a cooked ioctl CDROM.", idmessage(messagedest, ppsz_messages,
device); "\t\t%s is not a cooked ioctl CDROM.",
free(device); psz_device);
return(NULL); return(NULL);
} }
} }
@@ -242,7 +257,7 @@ cdda_identify_cooked(const char *dev, int messagedest, char **messages)
d=calloc(1,sizeof(cdrom_drive_t)); d=calloc(1,sizeof(cdrom_drive_t));
d->p_cdio = p_cdio; d->p_cdio = p_cdio;
d->cdda_device_name = device; d->cdda_device_name = strdup(psz_device);
d->drive_type = drive_type; d->drive_type = drive_type;
d->interface = COOKED_IOCTL; d->interface = COOKED_IOCTL;
d->bigendianp = -1; /* We don't know yet... */ d->bigendianp = -1; /* We don't know yet... */
@@ -269,10 +284,35 @@ cdda_identify_cooked(const char *dev, int messagedest, char **messages)
hw_info.psz_vendor, hw_info.psz_model, hw_info.psz_revision hw_info.psz_vendor, hw_info.psz_model, hw_info.psz_revision
); );
} }
idmessage(messagedest,messages,"\t\tCDROM sensed: %s\n", idmessage(messagedest, ppsz_messages, "\t\tCDROM sensed: %s\n",
d->drive_model); d->drive_model);
} }
} }
return(d); return(d);
} }
/* Really has nothing to with "cooked" mode. This is historical stuff
put in to fool folks who love to give opinions based on a
superficial reading of code. Down the line when we're ready to deal
with such folks, perhaps this routine should be renamed.
*/
cdrom_drive_t *
cdda_identify_cooked(const char *psz_dev, int messagedest,
char **ppsz_messages)
{
CdIo_t *p_cdio = NULL;
if (psz_dev) {
char *psz_device = test_resolve_symlink(psz_dev, messagedest,
ppsz_messages);
if ( psz_device ) {
p_cdio = cdio_open(psz_device, DRIVER_UNKNOWN);
return cdda_identify_device_cdio(p_cdio, psz_device, messagedest,
ppsz_messages);
}
}
p_cdio = cdio_open(psz_dev, DRIVER_UNKNOWN);
return cdda_identify_device_cdio(p_cdio, psz_dev, messagedest,
ppsz_messages);
}