⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _cdio_sunos.c

📁 linux下的MPEG1
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    $Id: _cdio_sunos.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $    Copyright (C) 2001 Herbert Valerio Riedel <hvr@gnu.org>    Copyright (C) 2002, 2003, 2004 Rocky Bernstein <rocky@panix.com>    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program 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 General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef HAVE_CONFIG_H# include "config.h"#endif#ifdef HAVE_STRING_H#include <string.h>#endif#include <cdio/logging.h>#include <cdio/sector.h>#include <cdio/util.h>#include <cdio/scsi_mmc.h>#include "cdio_assert.h"#include "cdio_private.h"#define DEFAULT_CDIO_DEVICE "/vol/dev/aliases/cdrom0"#ifdef HAVE_SOLARIS_CDROMstatic const char _rcsid[] = "$Id: _cdio_sunos.c,v 1.3 2005/01/01 02:43:57 rockyb Exp $";#ifdef HAVE_GLOB_H#include <glob.h>#endif#include <stdio.h>#include <stdlib.h>#include <errno.h>#include <unistd.h>#include <fcntl.h>#ifdef HAVE_SYS_CDIO_H# include <sys/cdio.h> /* CDIOCALLOW etc... */#else #error "You need <sys/cdio.h> to have CDROM support"#endif#include <sys/dkio.h>#include <sys/scsi/generic/commands.h>#include <sys/scsi/impl/uscsi.h>#include <sys/stat.h>#include <sys/types.h>#include <sys/ioctl.h>#include "cdtext_private.h"/* not defined in dkio.h yet */#define DK_DVDRW 0x13/* reader */typedef  enum {    _AM_NONE,    _AM_SUN_CTRL_ATAPI,    _AM_SUN_CTRL_SCSI#if FINISHED    _AM_READ_CD,    _AM_READ_10#endif} access_mode_t;typedef struct {  /* Things common to all drivers like this.      This must be first. */  generic_img_private_t gen;     access_mode_t access_mode;  /* Some of the more OS specific things. */  /* Entry info for each track, add 1 for leadout. */  struct cdrom_tocentry  tocent[CDIO_CD_MAX_TRACKS+1];   /* Track information */  struct cdrom_tochdr    tochdr;} _img_private_t;static track_format_t get_track_format_solaris(void *p_user_data, 					       track_t i_track);static access_mode_t str_to_access_mode_sunos(const char *psz_access_mode) {  const access_mode_t default_access_mode = _AM_SUN_CTRL_SCSI;  if (NULL==psz_access_mode) return default_access_mode;    if (!strcmp(psz_access_mode, "ATAPI"))    return _AM_SUN_CTRL_SCSI; /* force ATAPI to be SCSI */  else if (!strcmp(psz_access_mode, "SCSI"))    return _AM_SUN_CTRL_SCSI;  else {    cdio_warn ("unknown access type: %s. Default SCSI used.", 	       psz_access_mode);    return default_access_mode;  }}/*!  Initialize CD device. */static boolinit_solaris (_img_private_t *p_env){  if (!cdio_generic_init(p_env)) return false;    p_env->access_mode = _AM_SUN_CTRL_SCSI;      return true;}/*!  Run a SCSI MMC command.    p_user_data   internal CD structure.  i_timeout_ms   time in milliseconds we will wait for the command                to complete.   i_cdb	        Size of p_cdb  p_cdb	        CDB bytes.   e_direction	direction the transfer is to go.  i_buf	        Size of buffer  p_buf	        Buffer for data, both sending and receiving  Return 0 if no error. */static intrun_scsi_cmd_solaris( const void *p_user_data, unsigned int i_timeout_ms,		      unsigned int i_cdb, const scsi_mmc_cdb_t *p_cdb, 		      scsi_mmc_direction_t e_direction, 		      unsigned int i_buf, /*in/out*/ void *p_buf ){  const _img_private_t *p_env = p_user_data;  struct uscsi_cmd cgc;  memset (&cgc, 0, sizeof (struct uscsi_cmd));  cgc.uscsi_cdb = (caddr_t) p_cdb;  cgc.uscsi_flags = SCSI_MMC_DATA_READ == e_direction ?     USCSI_READ : USCSI_WRITE;  cgc.uscsi_timeout = msecs2secs(i_timeout_ms);  cgc.uscsi_bufaddr = p_buf;     cgc.uscsi_buflen  = i_buf;  cgc.uscsi_cdblen  = i_cdb;    return ioctl(p_env->gen.fd, USCSICMD, &cgc);}/*!   Reads audio sectors from CD device into data starting from lsn.   Returns 0 if no error.    May have to check size of nblocks. There may be a limit that   can be read in one go, e.g. 25 blocks.*/static int_read_audio_sectors_solaris (void *p_user_data, void *data, lsn_t lsn, 			  unsigned int nblocks){  struct cdrom_msf solaris_msf;  msf_t _msf;  struct cdrom_cdda cdda;  _img_private_t *p_env = p_user_data;  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);  solaris_msf.cdmsf_min0   = cdio_from_bcd8(_msf.m);  solaris_msf.cdmsf_sec0   = cdio_from_bcd8(_msf.s);  solaris_msf.cdmsf_frame0 = cdio_from_bcd8(_msf.f);    if (p_env->gen.ioctls_debugged == 75)    cdio_debug ("only displaying every 75th ioctl from now on");    if (p_env->gen.ioctls_debugged == 30 * 75)    cdio_debug ("only displaying every 30*75th ioctl from now on");    if (p_env->gen.ioctls_debugged < 75       || (p_env->gen.ioctls_debugged < (30 * 75)  	  && p_env->gen.ioctls_debugged % 75 == 0)      || p_env->gen.ioctls_debugged % (30 * 75) == 0)    cdio_debug ("reading %d", lsn);    p_env->gen.ioctls_debugged++;    cdda.cdda_addr    = lsn;  cdda.cdda_length  = nblocks;  cdda.cdda_data    = (caddr_t) data;  cdda.cdda_subcode = CDROM_DA_NO_SUBCODE;    if (ioctl (p_env->gen.fd, CDROMCDDA, &cdda) == -1) {    perror ("ioctl(..,CDROMCDDA,..)");	return 1;	/* exit (EXIT_FAILURE); */  }    return 0;}/*!   Reads a single mode1 sector from cd device into data starting   from lsn. Returns 0 if no error.  */static int_read_mode1_sector_solaris (void *env, void *data, lsn_t lsn, 			    bool b_form2){#if FIXED  do something here. #else  return cdio_generic_read_form1_sector(env, data, lsn);#endif}/*!   Reads nblocks of mode2 sectors from cd device into data starting   from lsn.   Returns 0 if no error.  */static int_read_mode1_sectors_solaris (void *p_user_data, void *p_data, lsn_t lsn, 			     bool b_form2, unsigned int nblocks){  _img_private_t *p_env = p_user_data;  unsigned int i;  int retval;  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;  for (i = 0; i < nblocks; i++) {    if ( (retval = _read_mode1_sector_solaris (p_env, 					    ((char *)p_data) + (blocksize * i),					       lsn + i, b_form2)) )      return retval;  }  return 0;}/*!   Reads a single mode2 sector from cd device into data starting from lsn.   Returns 0 if no error.  */static int_read_mode2_sector_solaris (void *p_user_data, void *p_data, lsn_t lsn, 			    bool b_form2){  char buf[CDIO_CD_FRAMESIZE_RAW] = { 0, };  struct cdrom_msf solaris_msf;  msf_t _msf;  int offset = 0;  struct cdrom_cdxa cd_read;  _img_private_t *p_env = p_user_data;  cdio_lba_to_msf (cdio_lsn_to_lba(lsn), &_msf);  solaris_msf.cdmsf_min0   = cdio_from_bcd8(_msf.m);  solaris_msf.cdmsf_sec0   = cdio_from_bcd8(_msf.s);  solaris_msf.cdmsf_frame0 = cdio_from_bcd8(_msf.f);    if (p_env->gen.ioctls_debugged == 75)    cdio_debug ("only displaying every 75th ioctl from now on");    if (p_env->gen.ioctls_debugged == 30 * 75)    cdio_debug ("only displaying every 30*75th ioctl from now on");    if (p_env->gen.ioctls_debugged < 75       || (p_env->gen.ioctls_debugged < (30 * 75)  	  && p_env->gen.ioctls_debugged % 75 == 0)      || p_env->gen.ioctls_debugged % (30 * 75) == 0)    cdio_debug ("reading %2.2d:%2.2d:%2.2d",		solaris_msf.cdmsf_min0, solaris_msf.cdmsf_sec0, 		solaris_msf.cdmsf_frame0);    p_env->gen.ioctls_debugged++;    /* Using CDROMXA ioctl will actually use the same uscsi command   * as ATAPI, except we don't need to be root   */        offset = CDIO_CD_XA_SYNC_HEADER;  cd_read.cdxa_addr = lsn;  cd_read.cdxa_data = buf;  cd_read.cdxa_length = 1;  cd_read.cdxa_format = CDROM_XA_SECTOR_DATA;  if (ioctl (p_env->gen.fd, CDROMCDXA, &cd_read) == -1) {    perror ("ioctl(..,CDROMCDXA,..)");    return 1;    /* exit (EXIT_FAILURE); */  }    if (b_form2)    memcpy (p_data, buf + (offset-CDIO_CD_SUBHEADER_SIZE), M2RAW_SECTOR_SIZE);  else    memcpy (((char *)p_data), buf + offset, CDIO_CD_FRAMESIZE);    return 0;}/*!   Reads nblocks of mode2 sectors from cd device into data starting   from lsn.   Returns 0 if no error.  */static int_read_mode2_sectors_solaris (void *p_user_data, void *data, lsn_t lsn, 			     bool b_form2, unsigned int nblocks){  _img_private_t *env = p_user_data;  unsigned int i;  int retval;  unsigned int blocksize = b_form2 ? M2RAW_SECTOR_SIZE : CDIO_CD_FRAMESIZE;  for (i = 0; i < nblocks; i++) {    if ( (retval = _read_mode2_sector_solaris (env, 					    ((char *)data) + (blocksize * i),					       lsn + i, b_form2)) )      return retval;  }  return 0;}/*!   Return the size of the CD in logical block address (LBA) units. */static uint32_t _cdio_stat_size (void *p_user_data){  _img_private_t *env = p_user_data;  struct cdrom_tocentry tocent;  uint32_t size;  tocent.cdte_track  = CDIO_CDROM_LEADOUT_TRACK;  tocent.cdte_format = CDIO_CDROM_LBA;  if (ioctl (env->gen.fd, CDROMREADTOCENTRY, &tocent) == -1)    {      perror ("ioctl(CDROMREADTOCENTRY)");      exit (EXIT_FAILURE);    }  size = tocent.cdte_addr.lba;  return size;}/*!  Set the arg "key" with "value" in the source device.  Currently "source" and "access-mode" are valid keys.  "source" sets the source device in I/O operations   "access-mode" sets the the method of CD access   0 is returned if no error was found, and nonzero if there as an error.*/static int_set_arg_solaris (void *p_user_data, const char key[], const char value[]){  _img_private_t *env = p_user_data;  if (!strcmp (key, "source"))    {      if (!value)	return -2;      free (env->gen.source_name);            env->gen.source_name = strdup (value);    }  else if (!strcmp (key, "access-mode"))    {      env->access_mode = str_to_access_mode_sunos(key);    }  else     return -1;  return 0;}/*!   Read and cache the CD's Track Table of Contents and track info.  Return true if successful or false if an error.*/static boolread_toc_solaris (void *p_user_data) {  _img_private_t *p_env = p_user_data;  int i;  /* read TOC header */  if ( ioctl(p_env->gen.fd, CDROMREADTOCHDR, &p_env->tochdr) == -1 ) {    cdio_warn("%s: %s\n",             "error in ioctl CDROMREADTOCHDR", strerror(errno));    return false;  }  p_env->gen.i_first_track = p_env->tochdr.cdth_trk0;  p_env->gen.i_tracks      = p_env->tochdr.cdth_trk1;    /* read individual tracks */  for (i=p_env->gen.i_first_track; i<=p_env->gen.i_tracks; i++) {    p_env->tocent[i-1].cdte_track = i;    p_env->tocent[i-1].cdte_format = CDIO_CDROM_MSF;    if ( ioctl(p_env->gen.fd, CDROMREADTOCENTRY, &p_env->tocent[i-1]) == -1 ) {      cdio_warn("%s %d: %s\n",              "error in ioctl CDROMREADTOCENTRY for track",               i, strerror(errno));      return false;    }  }  /* read the lead-out track */  p_env->tocent[p_env->tochdr.cdth_trk1].cdte_track = CDIO_CDROM_LEADOUT_TRACK;  p_env->tocent[p_env->tochdr.cdth_trk1].cdte_format = CDIO_CDROM_MSF;  if (ioctl(p_env->gen.fd, CDROMREADTOCENTRY, 	    &p_env->tocent[p_env->tochdr.cdth_trk1]) == -1 ) {    cdio_warn("%s: %s\n", 	     "error in ioctl CDROMREADTOCENTRY for lead-out",            strerror(errno));    return false;  }  p_env->gen.toc_init = true;  return true;}/*!  Eject media in CD drive. If successful, as a side effect we   also free obj. */static int eject_media_solaris (void *p_user_data) {  _img_private_t *env = p_user_data;  int ret;  close(env->gen.fd);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -