label_cdrom.c revision 18c2aff776a775d34a4c9893a4c72e0434d68e36
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1996 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include "vold.h"
/*
* This labeling code is for cdrom. The fundamental
* assumption is that you can't write to a cdrom, and that there
* can easily be more than one of a particular cdrom. So, what
* we do is pick a few "interesting" sectors, create a crc of
* them, and use our crc's to match them up.
*
* Currently, we just generate one checksum based on the first
* 64kbytes of data.
*
*/
#define CD_MAXNAME ISO_VOL_ID_STRLEN
struct cd_label {
/* name derived from media */
};
static void cdrom_setup(vol_t *);
#define CDTYPE_DATA 1
#define CDTYPE_AUDIO 2
#define CDTYPE_MIXED 3
#define CDROM_VERSION 1
#define CDROM_SIZE sizeof (struct cd_label)
/* for CD-ROM "signature" -- must be a multiple of ISO_SECTOR_SIZE */
/* use the md4 digital signature */
#define CDROM_MD4
/* size of buffer used for printing longlong numbers */
#define CDROM_NUMBUFLEN 512
/* for identifying "CD-I"-type CD-ROMs */
#define CDI_ID_STRING "CD-I"
#define CDI_ID_STRLEN 4
/*
* the vold interface structure
*/
static struct labsw cdromlabsw = {
cdrom_key, /* l_key */
cdrom_compare, /* l_compare */
cdrom_read, /* l_read */
NULL, /* l_write */
cdrom_setup, /* l_setup */
cdrom_xdr, /* l_xdr */
(size_t)0, /* l_size */
(size_t)0, /* l_xdrsize */
ISO9660_LTYPE, /* l_ident */
(uint_t)0, /* l_nll */
};
/*
* Initialization function, called by the dso loader.
*/
{
return (TRUE);
}
/*
* this routine tries to find out about the CD-ROM specified
*
* it creates and partially fills in the cdl private CD-ROM data structure
*
* if it appears as if the CD-ROM is music-only (see rmmount/audio_only())
* it does not even try to find the name by reading data from the CD-ROM
*/
static enum laread_res
{
struct cdrom_tochdr th;
struct cdrom_tocentry te;
uchar_t i; /* track index */
/*
* can't even read the TOC header -- assume it's not music
* for now (the read attempt below will fail if it is)
*/
goto not_audio_only;
}
/*
* look through the tracks on the disk to see if we have
* any data (i.e. non-music) tracks
*/
/* if start track is greater than end track then assume not audio */
"cdrom: start track greater than end track\n"));
goto not_audio_only;
}
/* look for data on this track */
/* try to read the TOC entry for the ith track */
te.cdte_track = i;
/*
* oh oh: can't read track TOC entry - punt and
* try the LEADOUT track
*/
/*
* we can read TOC hdr but not the TOC entry
* or the LEADOUT track -- assume not
* music for now (the read attempt
* below will fail if it is a music CD)
*/
"cdrom: readtocentry LEADOUT on \"%s\"; %m\n"),
audio_only = FALSE;
break;
}
/* if datamode is 2 then we have a mode 2 CD-ROM */
debug(5,
"cdrom_read: found Mode 2 data on LEADOUT track\n");
}
/*
* read TOC hdr succeeded but read of TOC entry for a
* track failed -- *guess* whether or not CD is audio
* only based on LEADOUT track
*/
audio_only = FALSE;
break;
}
/* *guess* audio only */
goto dun;
}
/*
* read of the ith track succeeded
*/
/* if datamode is 2 then we have a mode 2 CD-ROM */
(unsigned int)i);
}
/*
* if this (or any) track is non-audio then we set a flag
* saying this isn't a strickly-audio CD-ROM
*/
audio_only = FALSE;
}
/* go look at next one */
}
if (audio_only) {
/* all tracks found were audio */
goto dun;
}
/* find the CD's "name" */
/* set the type to data (since it is not music) */
/*
* now get a bigger buffer to do the "signature" on (if possible)
*
* call read routine to read CD_READSIZE bytes (if possible) from
* the CD-ROM
*/
if (!we_have_mode_2_data) {
/* just a "regular" ISO CD-ROM -- just read a hunk from it */
sz = CD_READSIZE;
"cdrom_read: can't read the cdrom; %m\n"));
goto dun;
}
} else {
/*
* use the sector we just read -- since Solaris doesn't
* seem able to handle non-2048 block mode 2 data (i.e.
* mode 2 form 2 -- it does handle form1, which are 2048
* byte blocks, like all mode 1 blocks) -- whew!
*/
}
/* calculate the "signature" */
#ifdef CDROM_MD4
#else
#endif
/* read the vtoc and convert that to #parts and a part bitmap */
dun:
#ifdef DEBUG
#endif
return (res);
}
static char *
{
} else {
#ifdef CDROM_MD4
#else
#endif
}
}
static bool_t
{
return (FALSE);
}
return (TRUE);
}
return (FALSE);
}
#ifdef CDROM_MD4
return (TRUE);
}
return (FALSE);
#else
return (TRUE);
}
return (FALSE);
#endif
}
return (FALSE);
}
static void
cdrom_setup(vol_t *v)
{
} else {
}
#ifdef DEBUG
#endif
}
void
{
char *s = NULL;
if (cdromlabsw.l_xdrsize == 0) {
cdromlabsw.l_xdrsize = 0;
(void *)&sdc.cl_version);
(void *)&sdc.cl_au_start);
}
if (op == XDR_ENCODE) {
xdr_destroy(&xdrs);
} else if (op == XDR_DECODE) {
l->l_label =
}
if (s) {
xdr_free(xdr_string, (void *)&s);
}
} else {
debug(1,
"label_cdrom: don't know how to decode version %d\n",
cdl->cl_version);
}
xdr_destroy(&xdrs);
}
}
struct audiosum {
struct cdrom_tochdr as_th;
/* max number of tracks is 99 + 1 for lead-in */
};
static u_long
{
uchar_t i;
}
}
}
}
return (crc);
}
/*
* We've already read the data, so there's no reason not to check
* and see if we have an HSFS disk with a nice name out there.
*/
static void
{
char *nm;
int err;
int off = 0;
#ifdef CDROMREADOFFSET
off = 0;
#endif
}
}
#ifdef DEBUG
else {
}
#endif
}
static bool_t
{
int i;
#ifdef DEBUG
char *volid;
#endif
#ifdef DEBUG
#endif
/* if this is the end of volume descriptors then bail */
break;
}
/* do we have a "CD-I" string ?? */
for (i = 0; i < CDI_ID_STRLEN; i++) {
break;
}
}
if (i < CDI_ID_STRLEN) {
break; /* string didn't match */
}
continue; /* not a valid sector? */
}
/* what type of sector is this */
#ifdef DEBUG
volid);
#endif
break;
}
/* look at next sector */
}
#ifdef DEBUG
#endif
return (found);
}
/*ARGSUSED*/
static bool_t
{
int i;
#ifdef DEBUG
char *volid;
#endif
#ifdef DEBUG
#endif
/*
* look through the volume descriptors until we find an HSFS
* primary volume descriptor, or until we find the end of the
* volume descriptors
*/
/* found the end of the vol descriptors */
break; /* not found */
}
for (i = 0; i < HSV_ID_STRLEN; i++) {
break; /* not a match */
}
}
if (i < HSV_ID_STRLEN) {
break; /* not a match */
}
break; /* not a match */
}
#ifdef DEBUG
volid);
#endif
break;
}
/* go to the next sector */
}
#ifdef DEBUG
#endif
return (found);
}
/*ARGSUSED*/
static bool_t
{
int i;
#ifdef DEBUG
char *volid;
#endif
#ifdef DEBUG
#endif
/*
* look through the volume descriptors until we find an ISO 9660
* primary volume descriptor, or until we find the end of the
* volume descriptors
*/
/* found the end of the vol descriptors */
break; /* not found */
}
for (i = 0; i < ISO_ID_STRLEN; i++) {
break; /* not a match */
}
}
if (i < ISO_ID_STRLEN) {
break; /* string didn't match */
}
break; /* not a match */
}
#ifdef DEBUG
volid);
#endif
break;
}
/* no match -- go to the next sector */
}
#ifdef DEBUG
#endif
return (found);
}
static bool_t
{
#ifdef DEBUG
errno);
#endif
return (FALSE);
}
#ifdef DEBUG
#endif
return (FALSE);
}
/* all went well */
return (TRUE);
}