Beispiel #1
0
static PyObject *
S_get_toc(PyObject *self, PyObject *args)
{
    int fd;
    int newlist = 0;
    char *device_nodename;
    PyObject *tracks = NULL;
    if(!PyArg_ParseTuple(args, "s|O", &device_nodename, &tracks)) return NULL;
    fd = opendev(device_nodename, O_RDONLY | O_NONBLOCK, 0, &device_nodename);
    if(fd == -1)
    {
        PyErr_SetFromErrnoWithFilename(PyExc_IOError, device_nodename);
        goto end;
    }
    if (tracks == NULL) {
        tracks = PyList_New(0);
        newlist = 1;
    }
    if(read_toc(fd, _get_toc_callback, (void*)tracks) == -1)
    {
        PyErr_SetFromErrnoWithFilename(PyExc_IOError, device_nodename);
        goto error;
    }
    // catch exceptions from callbacks
    if(PyErr_Occurred() != NULL) goto error;
    end:
    close(fd);
    if (!newlist){ Py_INCREF(tracks); }
    return tracks;
    error:
    if (newlist){ Py_XDECREF(tracks); }
    tracks = NULL;
    goto end;
}
Beispiel #2
0
/*! Play an audio track. */
static bool
play_track(track_t i_start_track, track_t i_end_track)
{
  bool b_ok = true;

  if (!b_cd) {
    cd_close(psz_device);
    read_toc(p_cdio);
  }

  read_subchannel(p_cdio);
  if (!b_cd || i_first_track == CDIO_CDROM_LEADOUT_TRACK)
    return false;

  if (debug)
    fprintf(stderr,"play tracks: %d-%d => ", i_start_track, i_end_track);
  if (i_start_track < i_first_track)       i_start_track = i_first_track;
  if (i_start_track > i_last_audio_track)  i_start_track = i_last_audio_track;
  if (i_end_track < i_first_track)         i_end_track   = i_first_track;
  if (i_end_track > i_last_audio_track)    i_end_track   = i_last_audio_track;
  if (debug)
    fprintf(stderr,"%d-%d\n",i_start_track, i_end_track);

  cd_pause(p_cdio);
  b_ok = (DRIVER_OP_SUCCESS == cdio_audio_play_msf(p_cdio,
						   &(toc[i_start_track]),
						   &(toc[i_end_track])) );
  if (!b_ok) xperror("play");
  return b_ok;
}
Beispiel #3
0
/** Play an audio track. */
static bool
play_track(track_t i_start_track, track_t i_end_track)
{
  bool b_ok = true;
  char line[80];
  
  if (!b_cd) {
    read_toc(p_cdio);
  }
  
  read_subchannel(p_cdio);
  if (!b_cd || i_first_track == CDIO_CDROM_LEADOUT_TRACK)
    return false;
  
  if (debug)
    fprintf(stderr,"play tracks: %d-%d => ", i_start_track, i_end_track-1);
  if (i_start_track < i_first_track)       i_start_track = i_first_track;
  if (i_start_track > i_last_audio_track)  i_start_track = i_last_audio_track;
  if (i_end_track < i_first_track)         i_end_track   = i_first_track;
  if (i_end_track > i_last_audio_track)    i_end_track   = i_last_audio_track;
  i_end_track++;
  if (debug)
    fprintf(stderr,"%d-%d\n",i_start_track, i_end_track-1);
  
  cd_pause(p_cdio);
  snprintf(line, sizeof(line), "play track %d to track %d.", 
	   i_start_track, i_end_track-1);
  action(line);
  b_ok = (DRIVER_OP_SUCCESS == cdio_audio_play_msf(p_cdio, 
                                                   &(toc[i_start_track]),
                                                   &(toc[i_end_track])) );
  if (!b_ok) xperror("play");
  return b_ok;
}
Beispiel #4
0
int
cddb_resolve(const char *dev, char **xmcd_file) {
	char cddb_cache_dir[] = DEFAULT_CACHE_DIR;
	char *home_dir = NULL;
	cddb_data_t cddb_data;

	if (cdtoc_last_track <= 0)
	{
	    cdtoc_last_track = read_toc(dev);
	    if (cdtoc_last_track < 0) {
		mp_msg(MSGT_OPEN, MSGL_ERR, MSGTR_MPDEMUX_CDDB_FailedToOpenDevice, dev);
		return -1;
	    }
	}
	cddb_data.tracks = cdtoc_last_track;
	cddb_data.disc_id = cddb_discid(cddb_data.tracks);
	cddb_data.anonymous = 1;	// Don't send user info by default

	// Check if there is a CD in the drive
	// FIXME: That's not really a good way to check
	if( cddb_data.disc_id==0 ) {
		mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MPDEMUX_CDDB_NoCDInDrive);
		return -1;
	}
	
	home_dir = getenv("HOME");
#ifdef __MINGW32__
	if( home_dir==NULL ) home_dir = getenv("USERPROFILE");
	if( home_dir==NULL ) home_dir = getenv("HOMEPATH");
	// Last resort, store the cddb cache in the mplayer directory
	if( home_dir==NULL ) home_dir = (char *)get_path("");
#endif
	if( home_dir==NULL ) {
		cddb_data.cache_dir = NULL;
	} else {
		cddb_data.cache_dir = malloc(strlen(home_dir)+strlen(cddb_cache_dir)+1);
		if( cddb_data.cache_dir==NULL ) {
			mp_msg(MSGT_DEMUX, MSGL_ERR, MSGTR_MemAllocFailed);
			return -1;
		}
		sprintf(cddb_data.cache_dir, "%s%s", home_dir, cddb_cache_dir );
	}

	// Check for a cached file
	if( cddb_read_cache(&cddb_data)<0 ) {
		// No Cache found
		if( cddb_retrieve(&cddb_data)<0 ) {
			return -1;
		}
	}

	if( cddb_data.xmcd_file!=NULL ) {
//		printf("%s\n", cddb_data.xmcd_file );
		*xmcd_file = cddb_data.xmcd_file;
		return 0;
	}
	
	return -1;
}
Beispiel #5
0
void CddaImpl::open()
{
   driver_id_t driver_id = DRIVER_UNKNOWN;

   if (_device.empty())
   {
   char **ppsz_cd_drives = cdio_get_devices_with_cap_ret(NULL,  
                                                         CDIO_FS_AUDIO, 
                                                         false,
                                                         &driver_id);
   if (ppsz_cd_drives && *ppsz_cd_drives)
      _device = ppsz_cd_drives[0];

   cdio_free_device_list(ppsz_cd_drives);
   }

   _cdio = cdio_open(_device.c_str(), driver_id);

   if (_cdio == NULL) 
   {
      THROW_EXCEPTION(CddaException, "Could not open device.");
   }

   // Detect empty drive   
   if (cdio_get_first_track_num(_cdio) == CDIO_INVALID_TRACK) 
   {
      close();
      return;
   }

   _cdrom = cdio_cddap_identify_cdio(_cdio, CDDA_MESSAGE_LOGIT, NULL);

   if (_cdrom == NULL) 
   {
      THROW_EXCEPTION(CddaException, "Could not read cdrom structure.");
   }

   cdio_cddap_verbose_set(_cdrom, CDDA_MESSAGE_LOGIT, CDDA_MESSAGE_LOGIT);

   int ret = cdio_cddap_open(_cdrom);
   if (ret != 0) 
   {
      THROW_EXCEPTION(CddaException, cdda_error_message(ret));
   }

   _is_open = true;

   read_toc();
   //read_cddb();
}
Beispiel #6
0
static void
read_outline (PopplerDocument *document,
              TrackerResource *metadata)
{
    PopplerIndexIter *index;
    GString *toc = NULL;

    index = poppler_index_iter_new (document);

    if (!index) {
        return;
    }

    read_toc (index, &toc);

    if (toc) {
        if (toc->len > 0) {
            tracker_resource_set_string (metadata, "nfo:tableOfContents", toc->str);
        }

        g_string_free (toc, TRUE);
    }
}
Beispiel #7
0
/**
\brief Reads TOC from CD in the given device and prints the number of tracks
       and the length of each track in minute:second:frame format.
\param *dev the device to analyse
\return if the command line -identify is given, returns the last track of
        the TOC or -1 if the TOC can't be read,
        otherwise just returns 0 and let cddb_resolve the TOC
*/
int cdd_identify(const char *dev)
{
    cdtoc_last_track = 0;
    if (mp_msg_test(MSGT_IDENTIFY, MSGL_INFO)) {
        int i, min, sec, frame;
        cdtoc_last_track = read_toc(dev);
        if (cdtoc_last_track < 0) {
            mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev);
            return -1;
        }
        mp_msg(MSGT_GLOBAL, MSGL_INFO, "ID_CDDA_TRACKS=%d\n", cdtoc_last_track);
        for (i = 1; i <= cdtoc_last_track; i++) {
            frame  = cdtoc[i].frame - cdtoc[i-1].frame;
            sec    = frame / 75;
            frame -= sec * 75;
            min    = sec / 60;
            sec   -= min * 60;
            mp_msg(MSGT_IDENTIFY, MSGL_INFO,
                   "ID_CDDA_TRACK_%d_MSF=%02d:%02d:%02d\n", i, min, sec, frame);
        }
    }
    return cdtoc_last_track;
}
Beispiel #8
0
static void
read_outline (PopplerDocument      *document,
              TrackerSparqlBuilder *metadata)
{
	PopplerIndexIter *index;
	GString *toc = NULL;

	index = poppler_index_iter_new (document);

	if (!index) {
		return;
	}

	read_toc (index, &toc);

	if (toc) {
		if (toc->len > 0) {
			tracker_sparql_builder_predicate (metadata, "nfo:tableOfContents");
			tracker_sparql_builder_object_unvalidated (metadata, toc->str);
		}

		g_string_free (toc, TRUE);
	}
}
Beispiel #9
0
static int open_vcd(bgav_input_context_t * ctx, const char * url, char ** r)
  {
  driver_return_code_t err;
  int i;
  vcd_priv * priv;
  const char * pos;

  //  bgav_find_devices_vcd();
    
  priv = calloc(1, sizeof(*priv));
  
  ctx->priv = priv;

#ifndef SECTOR_ACCESS
  priv->buffer = priv->sector + 8;
  priv->buffer_ptr = priv->buffer + SECTOR_SIZE;
#endif

  pos = strrchr(url, '.');
  if(pos && !strcasecmp(pos, ".cue"))
    priv->cdio = cdio_open (url, DRIVER_BINCUE);
  else
    {
    if((err = cdio_close_tray(url, NULL)))
#if LIBCDIO_VERSION_NUM >= 77
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "cdio_close_tray failed: %s",
              cdio_driver_errmsg(err));
#else
      bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
               "cdio_close_tray failed");
#endif    
    
    priv->cdio = cdio_open (url, DRIVER_DEVICE);

    /* Close tray, hope this won't be harmful if the
       tray is already closed */

    }
  if(!priv->cdio)
    {
    bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
             "cdio_open failed for %s", url);
    return 0;
    }
  /* Get some infos */

  //  dump_cdrom(priv->fd);
  
  /* Read TOC */
  
  if(!read_toc(priv, &ctx->disc_name))
    {
    bgav_log(ctx->opt, BGAV_LOG_ERROR, LOG_DOMAIN,
             "read_toc failed for %s", url);
    return 0;
    }
  toc_2_tt(ctx);

  /* Set up sector stuff */

#ifdef SECTOR_ACCESS
  ctx->sector_size        = 2324;
  ctx->sector_size_raw    = 2352;
  ctx->sector_header_size = 8;
#endif
  
  /* Create demuxer */
  
  ctx->demuxer = bgav_demuxer_create(ctx->opt, &bgav_demuxer_mpegps, ctx);
  ctx->demuxer->tt = ctx->tt;

  /* Now, loop through all tracks and let the demuxer find the durations */

  for(i = 0; i < ctx->tt->num_tracks; i++)
    {
    select_track_vcd(ctx, i);
    bgav_track_table_select_track(ctx->tt, i);
    bgav_demuxer_start(ctx->demuxer, NULL);
    bgav_demuxer_stop(ctx->demuxer);
    }
  ctx->can_pause = 1;
  return 1;
  }
Beispiel #10
0
static dbus_bool_t
probe_disc (int fd, LibHalContext *ctx, const char *udi, dbus_bool_t *has_data,
    dbus_bool_t *has_audio)
{
	DBusError error;
	disc_info_t di;
	int profile;
	dbus_bool_t is_blank, is_appendable, is_rewritable;
	char *disc_type = "cd_rom";
	uint64_t capacity = 0;
	int i;
	LibHalChangeSet *cs;

	dbus_error_init (&error);

	if (get_disc_info (fd, &di)) {
		is_blank = (di.disc_status == 0);
		is_appendable = (di.disc_status == 1);
		is_rewritable = (di.erasable != 0);
	} else {
		is_blank = is_appendable = is_rewritable = FALSE;
	}

	if (get_current_profile (fd, &profile)) {
		switch (profile) {
		case 0x08: /* CD-ROM */
			disc_type = "cd_rom";
			break;
		case 0x09: /* CD-R */
			disc_type = "cd_r";
			break;
		case 0x0A: /* CD-RW */
			disc_type = "cd_rw";
			is_rewritable = TRUE;
			break;
		case 0x10: /* DVD-ROM */
			disc_type = "dvd_rom";
			break;
		case 0x11: /* DVD-R Sequential */
			disc_type = "dvd_r";
			break;
		case 0x12: /* DVD-RAM */
			disc_type = "dvd_ram";
			is_rewritable = TRUE;
			break;
		case 0x13: /* DVD-RW Restricted Overwrite */
			disc_type = "dvd_rw";
			is_rewritable = TRUE;
			break;
		case 0x14: /* DVD-RW Sequential */
			disc_type = "dvd_rw";
			is_rewritable = TRUE;
			break;
		case 0x1A: /* DVD+RW */
			disc_type = "dvd_plus_rw";
			is_rewritable = TRUE;
			break;
		case 0x1B: /* DVD+R */
			disc_type = "dvd_plus_r";
			break;
		case 0x2B: /* DVD+R Double Layer */
                        disc_type = "dvd_plus_r_dl";
			break;
		case 0x40: /* BD-ROM */
                        disc_type = "bd_rom";
			break;
		case 0x41: /* BD-R Sequential */
                        disc_type = "bd_r";
			break;
		case 0x42: /* BD-R Random */
                        disc_type = "bd_r";
			break;
		case 0x43: /* BD-RE */
                        disc_type = "bd_re";
			is_rewritable = TRUE;
			break;
		case 0x50: /* HD DVD-ROM */
                        disc_type = "hddvd_rom";
			break;
		case 0x51: /* HD DVD-R */
                        disc_type = "hddvd_r";
			break;
		case 0x52: /* HD DVD-Rewritable */
                        disc_type = "hddvd_rw";
			is_rewritable = TRUE;
			break;
		}

		(void) get_disc_capacity_for_profile(fd, profile, &capacity);
	}

	*has_audio = *has_data = FALSE;
	if (!is_blank) {
		uchar_t	smalltoc[12];
		size_t	toc_size;
		uchar_t	*toc, *p;

		/*
		 * XXX for some reason CDROMREADTOCENTRY fails on video DVDs,
		 * but extracting the toc directly works okay.
		 */
        	if (!read_toc(fd, 0, 1, 4, smalltoc)) {
                	HAL_DEBUG(("read_toc failed"));
			*has_data = B_TRUE; /* probe for fs anyway */
        	} else {
        		toc_size = smalltoc[0] * 256 + smalltoc[1] + 2;
        		toc = (uchar_t *)calloc(1, toc_size);
        		if (toc == NULL || !read_toc(fd, 0, 1, toc_size, toc)) {
                		HAL_DEBUG (("read_toc again failed"));
        		} else {
        			for (p = &toc[4]; p < (toc + toc_size); p += 8) {
					/* skip leadout */
                			if (p[2] == 0xAA) {
						continue;
					}
					if (p[1] & 4) {
						*has_data = B_TRUE;
					} else {
						*has_audio = B_TRUE;
					}
        			}
			}
			free(toc);
		}
	}

	if ((cs = libhal_device_new_changeset (udi)) == NULL) {
		return (FALSE);
	}
	libhal_changeset_set_property_string (cs, "volume.disc.type", disc_type);
	libhal_changeset_set_property_bool (cs, "volume.disc.is_blank", is_blank);
	libhal_changeset_set_property_bool (cs, "volume.disc.has_audio", *has_audio);
	libhal_changeset_set_property_bool (cs, "volume.disc.has_data", *has_data);
	libhal_changeset_set_property_bool (cs, "volume.disc.is_appendable", is_appendable);
	libhal_changeset_set_property_bool (cs, "volume.disc.is_rewritable", is_rewritable);
	libhal_changeset_set_property_uint64 (cs, "volume.disc.capacity", capacity);

	libhal_changeset_set_property_bool (cs, "volume.disc.is_videodvd", FALSE);
	libhal_changeset_set_property_bool (cs, "volume.disc.is_vcd", FALSE);
	libhal_changeset_set_property_bool (cs, "volume.disc.is_svcd", FALSE);

	libhal_device_commit_changeset (ctx, cs, &error);
	libhal_device_free_changeset (cs);

out:
	my_dbus_error_free (&error);

	return (TRUE);
}
Beispiel #11
0
int
main(int argc, char *argv[])
{
  int  c;
  char *h;
  int  i_rc = 0;
  int  i_volume_level = -1;
  cd_operation_t todo = NO_OP; /* operation to do in non-interactive mode */

  psz_program = strrchr(argv[0],'/');
  psz_program = psz_program ? psz_program+1 : argv[0];

  /* parse options */
  while ( 1 ) {
    if (-1 == (c = getopt(argc, argv, "aCdehkpL:sSt:vx")))
      break;
    switch (c) {
    case 'v':
      b_verbose = true;
      break;
    case 'd':
      debug = 1;
      break;
    case 'a':
      auto_mode = 1;
      break;
    case 'L':
      if (NULL != strchr(optarg,'-')) {
	i_volume_level = atoi(optarg);
	todo = SET_VOLUME;
      }
      break;
    case 't':
      if (NULL != (h = strchr(optarg,'-'))) {
	*h = 0;
	start_track = atoi(optarg);
	stop_track = atoi(h+1)+1;
	if (0 == start_track) start_track = 1;
	if (1 == stop_track)  stop_track  = CDIO_CDROM_LEADOUT_TRACK;
      } else {
	start_track = atoi(optarg);
	stop_track = start_track+1;
	one_track = 1;
      }
      todo = PLAY_TRACK;
      break;
    case 'p':
      todo = PLAY_CD;
      break;
    case 'C':
      todo = CLOSE_CD;
      break;
      break;
    case 's':
      todo = STOP_PLAYING;
      break;
    case 'S':
      todo = LIST_SUBCHANNEL;
      break;
    case 'e':
      todo = EJECT_CD;
      break;
    case 'h':
      usage(psz_program);
      exit(1);
    default:
      usage(psz_program);
      exit(1);
    }
  }

  if (argc > optind) {
    psz_device = strdup(argv[optind]);
  } else {
    char **ppsz_cdda_drives=NULL;
    char **ppsz_all_cd_drives = cdio_get_devices_ret(&driver_id);

    if (!ppsz_all_cd_drives) {
      fprintf(stderr, "Can't find a CD-ROM drive\n");
      exit(2);
    }
    ppsz_cdda_drives = cdio_get_devices_with_cap(ppsz_all_cd_drives,
						 CDIO_FS_AUDIO, false);
    if (!ppsz_cdda_drives || !ppsz_cdda_drives[0]) {
      fprintf(stderr, "Can't find a CD-ROM drive with a CD-DA in it\n");
      exit(3);
    }
    psz_device = strdup(ppsz_cdda_drives[0]);
    cdio_free_device_list(ppsz_all_cd_drives);
    cdio_free_device_list(ppsz_cdda_drives);
  }

  if (!b_cd && todo != EJECT_CD) {
    cd_close(psz_device);
  }

  /* open device */
  if (b_verbose)
    fprintf(stderr,"open %s... ", psz_device);

  p_cdio = cdio_open (psz_device, driver_id);

  if (!p_cdio) {
    if (b_verbose)
      fprintf(stderr, "error: %s\n", strerror(errno));
    else
      fprintf(stderr, "open %s: %s\n", psz_device, strerror(errno));
    exit(1);
  } else
    if (b_verbose) fprintf(stderr,"ok\n");

  if (EJECT_CD == todo) {
    i_rc = cd_eject() ? 0 : 1;
  } else {
    read_toc(p_cdio);
    if (!b_cd) {
      cd_close(psz_device);
      read_toc(p_cdio);
    }
    if (b_cd)
      switch (todo) {
      case NO_OP:
	break;
      case STOP_PLAYING:
	i_rc = cd_stop(p_cdio) ? 0 : 1;
	break;
      case EJECT_CD:
	/* Should have been handled above before case statement. gcc
	   warns if we don't include this. And with this Coverty
	   complains when we do - we can't win, so go with gcc. */
	cd_eject();
	break;
	case PLAY_TRACK:
	  /* play just this one track */
	  play_track(start_track, stop_track);
	  break;
	case PLAY_CD:
	  play_track(1,CDIO_CDROM_LEADOUT_TRACK);
	  break;
	case CLOSE_CD:
	  i_rc = cdio_close_tray(psz_device, NULL) ? 0 : 1;
	  break;
	case SET_VOLUME:
	  {
	    cdio_audio_volume_t volume;
	    volume.level[0] = i_volume_level;
	    i_rc = (DRIVER_OP_SUCCESS == cdio_audio_set_volume(p_cdio,
							       &volume))
	      ? 0 : 1;
	    break;
	  }
	case LIST_SUBCHANNEL:
	  if (read_subchannel(p_cdio)) {
	    if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
		sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
	      {
		printf("track %2d - %02x:%02x (%02x:%02x abs) ",
		       sub.track, sub.rel_addr.m, sub.rel_addr.s,
		       sub.abs_addr.m, sub.abs_addr.s);
	      }
	    }
	    printf("drive state: %s\n",
		   mmc_audio_state2str(sub.audio_status));
	  } else {
	    i_rc = 1;
	  }
	  break;
      }
      else {
	fprintf(stderr,"no CD in drive (%s)\n", psz_device);
      }
  }

  oops("bye", i_rc);

  return 0; /* keep compiler happy */
}
Beispiel #12
0
/*
 * The size of the last track in one of the first N - 1 sessions of an
 * N-session (N > 1) disc is reported incorrectly by some drives and calculated
 * incorrectly for others, because a pre-gap/lead-out/lead-in section that ends
 * a session is erroneously considered part of that track. This function checks
 * for this corner case, and adjusts the track size if necessary.
 */
static int
check_track_size(cd_device *dev, int trk_num, struct track_info *tip)
{
	size_t raw_toc_len;
	uchar_t *raw_toc;
	rtoc_hdr_t hdr;
	uint32_t sess_leadout_lba;
	int sess_last_trk_num;
	int trk_sess_num;
	uint32_t trk_size;

	/* Request Raw TOC Header for session count. */
	if (read_toc(dev->d_fd, FORMAT_RAW_TOC, 1,
	    sizeof (rtoc_hdr_t), (uchar_t *)&hdr) != 1)
		return (0);

	/* Is this a multi-session medium? */
	if (hdr.rh_last_sess_num > hdr.rh_first_sess_num) {
		/* Yes; request entire Raw TOC. */
		raw_toc_len = read_scsi16(&hdr.rh_data_len1) + RTOC_DATA_LEN_SZ;
		raw_toc = (uchar_t *)my_zalloc(raw_toc_len);

		if (read_toc(dev->d_fd, FORMAT_RAW_TOC, 1, raw_toc_len, raw_toc)
		    != 1)
			goto fail;

		if (rtoc_get_trk_sess_num(raw_toc, raw_toc_len, trk_num,
		    &trk_sess_num) != 1)
			goto fail;

		tip->ti_session_no = trk_sess_num;
		tip->ti_flags |= TI_SESSION_NO_VALID;

		/* Is the track in one of the first N - 1 sessions? */
		if (trk_sess_num < hdr.rh_last_sess_num) {
			if (rtoc_get_sess_last_trk_num(raw_toc, raw_toc_len,
			    trk_sess_num, &sess_last_trk_num) != 1)
				goto fail;

			/* Is the track the last track in the session? */
			if (trk_num == sess_last_trk_num) {
				if (rtoc_get_sess_leadout_lba(raw_toc,
				    raw_toc_len, trk_sess_num,
				    &sess_leadout_lba) != 1)
					goto fail;

				trk_size = sess_leadout_lba -
				    tip->ti_start_address;

				/* Fix track size if it was too big. */
				if (tip->ti_track_size > trk_size)
					tip->ti_track_size = trk_size;
			}
		}
		free(raw_toc);
	}
	return (1);

fail:
	free(raw_toc);
	return (0);
}
Beispiel #13
0
/*
 * Builds track information database for track trackno. If trackno is
 * -1, builds the database for next blank track.
 */
int
build_track_info(cd_device *dev, int trackno, struct track_info *t_info)
{
	uchar_t *ti;
	uchar_t toc[20];		/* 2 entries + 4 byte header */
	int ret;

	(void) memset(t_info, 0, sizeof (*t_info));
	/* 1st try READ TRACK INFORMATION */
	ti = (uchar_t *)my_zalloc(TRACK_INFO_SIZE);
	t_info->ti_track_no = trackno;

	/* Gererate faked information for writing to DVD */
	if (device_type != CD_RW) {
		uint_t bsize;

		t_info->ti_flags = 0x3000;
		t_info->ti_track_no = 1;
		t_info->ti_session_no = 1;
		t_info->ti_track_mode = 0x4;
		t_info->ti_data_mode = 1;
		t_info->ti_start_address = 0;

		/* only 1 track on DVD make it max size */
		t_info->ti_track_size = read_format_capacity(target->d_fd,
		    &bsize);
		if (t_info->ti_track_size < MAX_CD_BLKS) {
			t_info->ti_track_size = MAX_DVD_BLKS;
		}

		t_info->ti_nwa = 0;
		t_info->ti_lra = 0;
		t_info->ti_packet_size = 0x10;
		t_info->ti_free_blocks = 0;
	}

	if (read_track_info(dev->d_fd, trackno, ti)) {

		if (debug)
			(void) printf("using read_track_info for TOC \n");

		t_info->ti_track_no = ti[2];
		t_info->ti_session_no = ti[3];
		t_info->ti_flags = (ti[6] >> 4) & 0xf;
		t_info->ti_flags |= (uint32_t)(ti[5] & 0xf0);
		t_info->ti_flags |= (uint32_t)(ti[7]) << 8;
		t_info->ti_flags |= TI_SESSION_NO_VALID | TI_FREE_BLOCKS_VALID;
		t_info->ti_track_mode = ti[5] & 0xf;
		if ((ti[6] & 0xf) == 0xf)
			t_info->ti_data_mode = 0xff;
		else
			t_info->ti_data_mode = ti[6] & 0xf;
		t_info->ti_start_address = read_scsi32(&ti[8]);
		t_info->ti_nwa = read_scsi32(&ti[12]);
		t_info->ti_free_blocks = read_scsi32(&ti[16]);
		t_info->ti_packet_size = read_scsi32(&ti[20]);
		t_info->ti_track_size = read_scsi32(&ti[24]);
		t_info->ti_lra = read_scsi32(&ti[28]);
		free(ti);
		return (1);
	}
	/* READ TRACK INFORMATION not supported, try other options */
	free(ti);
	/*
	 * We can get info for next blank track if READ TRACK INFO is not
	 * supported.
	 */
	if (trackno == -1)
		return (0);

	if (debug)
		(void) printf("using READ_TOC for TOC\n");

	/* Try Read TOC */
	if (!read_toc(dev->d_fd, 0, trackno, 20, toc)) {
		return (0);
	}
	t_info->ti_start_address = read_scsi32(&toc[8]);
	t_info->ti_track_mode = toc[5] & 0xf;
	t_info->ti_track_size = read_scsi32(&toc[16]) - read_scsi32(&toc[8]);
	t_info->ti_data_mode = get_data_mode(dev->d_fd, read_scsi32(&toc[8]));

	/* Numbers for audio tracks are always in 2K chunks */
	if ((dev->d_blksize == 512) && ((t_info->ti_track_mode & 4) == 0)) {
		t_info->ti_start_address /= 4;
		t_info->ti_track_size /= 4;
	}

	/* Now find out the session thing */
	ret = read_toc(dev->d_fd, 1, trackno, 12, toc);

	/*
	 * Make sure that the call succeeds and returns the requested
	 * TOC size correctly.
	 */

	if ((ret == 0) || (toc[1] != 0x0a)) {

		/* For ATAPI drives or old Toshiba drives */
		ret = read_toc_as_per_8020(dev->d_fd, 1, trackno, 12, toc);
	}
	/* If this goes through well TOC length will always be 0x0a */
	if (ret && (toc[1] == 0x0a)) {
		if (trackno >= toc[6]) {
			t_info->ti_session_no = toc[3];
			t_info->ti_flags |= TI_SESSION_NO_VALID;
		}
		/*
		 * This might be the last track of this session. If so,
		 * exclude the leadout and next lead in.
		 */
		if (trackno == (toc[6] - 1)) {
			/*
			 * 1.5 Min leadout + 1 min. leadin + 2 sec. pre-gap.
			 * For 2nd+ leadout it will be 0.5 min. But currently
			 * there is no direct way. And it will not happen
			 * for any normal case.
			 *
			 * 75 frames/sec, 60 sec/min, so leadin gap is
			 * ((1.5 +1)*60 + 2)*75 = 11400 frames (blocks)
			 */
			t_info->ti_track_size -= 11400;
		}
	}
	return (1);
}
Beispiel #14
0
int cddb_resolve(const char *dev, char **xmcd_file)
{
    char cddb_cache_dir[] = DEFAULT_CACHE_DIR;
    char *home_dir = NULL;
    cddb_data_t cddb_data;
    void *talloc_ctx = talloc_new(NULL);

    if (cdtoc_last_track <= 0) {
        cdtoc_last_track = read_toc(dev);
        if (cdtoc_last_track < 0) {
            mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s device.\n", dev);
            return -1;
        }
    }
    cddb_data.tracks    = cdtoc_last_track;
    cddb_data.disc_id   = cddb_discid(cddb_data.tracks);
    cddb_data.anonymous = 1;    // Don't send user info by default

    mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDB_DISCID=%08lx\n",
           cddb_data.disc_id);

    // Check if there is a CD in the drive
    // FIXME: That's not really a good way to check
    if (cddb_data.disc_id == 0) {
        mp_tmsg(MSGT_DEMUX, MSGL_ERR, "No CD in the drive.\n");
        return -1;
    }

    home_dir = getenv("HOME");
#ifdef __MINGW32__
    if (home_dir == NULL)
        home_dir = getenv("USERPROFILE");
    if (home_dir == NULL)
        home_dir = getenv("HOMEPATH");
    // Last resort, store the cddb cache in the mplayer directory
    if (home_dir == NULL)
        home_dir = (char *)talloc_steal(talloc_ctx,
                                        mp_find_user_config_file(""));
#endif
    if (home_dir == NULL) {
        cddb_data.cache_dir = NULL;
    } else {
        unsigned len = strlen(home_dir) + strlen(cddb_cache_dir) + 1;
        cddb_data.cache_dir = malloc(len);
        if (cddb_data.cache_dir == NULL) {
            mp_tmsg(MSGT_DEMUX, MSGL_ERR, "Memory allocation failed.\n");
            talloc_free(talloc_ctx);
            return -1;
        }
        snprintf(cddb_data.cache_dir, len, "%s%s", home_dir, cddb_cache_dir);
    }
    talloc_free(talloc_ctx);

    // Check for a cached file
    if (cddb_read_cache(&cddb_data) < 0) {
        // No Cache found
        if (cddb_retrieve(&cddb_data) < 0) {
            return -1;
        }
    }

    if (cddb_data.xmcd_file != NULL) {
//        printf("%s\n", cddb_data.xmcd_file);
        *xmcd_file = cddb_data.xmcd_file;
        return 0;
    }

    return -1;
}
Beispiel #15
0
void
info(void)
{
	uchar_t *toc, *p, *conf;
	int ret, toc_size;
	uint_t bsize;
	size_t cap = 0;
	char *msg;
	struct track_info *ti;

	msg = gettext("Cannot read Table of contents\n");

	get_media_type(target->d_fd);

	(void) printf(gettext("\nDevice : %.8s %.16s\n"),
	    &target->d_inq[8], &target->d_inq[16]);
	(void) printf(gettext("Firmware : Rev. %.4s (%.12s)\n"),
	    &target->d_inq[32], &target->d_inq[36]);

	if (check_device(target, CHECK_DEVICE_NOT_READY)) {
		(void) check_device(target, CHECK_NO_MEDIA |
		    EXIT_IF_CHECK_FAILED);
		(void) check_device(target, CHECK_DEVICE_NOT_READY |
		    EXIT_IF_CHECK_FAILED);
	}

	if (verbose != 0) {
		/*
		 * Determine the media type by reading the active profile
		 * from the profile list.
		 */
		(void) printf(gettext("Media Type : "));

		conf = (uchar_t *)my_zalloc(MMC_FTR_HDR_LEN);

		if (get_configuration(target->d_fd, MMC_FTR_PRFL_LIST,
		    MMC_FTR_HDR_LEN, conf))
			print_profile_name(read_scsi16(&conf[6]), 0, 1);
		else
			(void) printf(gettext("UNKNOWN\n"));

		free(conf);

		/*
		 * Get the start address of the last possible lead out.
		 */
		cap = get_last_possible_lba(target);

		/*
		 * The start address of the last possible leadout will only
		 * be zero if the disc is full or this drive does not support
		 * this method of determining capacity.
		 */
		if (cap == 0)
			cap = read_format_capacity(target->d_fd, &bsize);

		/*
		 * Since both methods of determining the capacity of the
		 * media count the correct number of blocks, just multiply
		 * the capacity by the block size.
		 */
		cap *= target->d_blksize;

		if (device_type == CD_RW) {
			(void) printf(gettext("Media Capacity : %.2f MB "),
			    ((double)cap/ONE_MB_BASE2));
		} else {
			/*
			 * For DVD's make sure we print out "Formatted Media
			 * Capacity". Don't do this for CD-RWs as only
			 * DVDs are formatted.
			 */
			(void) printf(gettext("Formatted Media Capacity : "
			    "%.2f GB "), ((double)cap/ONE_GB_BASE10));
		}

		cap /= target->d_blksize;
		(void) printf(gettext("(%u blocks)\n"), (uint_t)cap);
	}

	if (!check_device(target, CHECK_MEDIA_IS_NOT_BLANK)) {
		(void) printf(gettext("Media is blank\n"));
		exit(0);
	}

	/*  Find out the number of entries in the toc */
	toc = (uchar_t *)my_zalloc(12);
	if (!read_toc(target->d_fd, 0, 1, 4, toc)) {
		err_msg(msg);
	} else {
		toc_size = 256*toc[0] + toc[1] + 2;
		free(toc);

		/* allocate enough space for each track entry */
		toc = (uchar_t *)my_zalloc(toc_size);

		if (!read_toc(target->d_fd, 0, 1, toc_size, toc)) {
			err_msg(msg);
			exit(1);
		}
		(void) printf("\n");

		/* l10n_NOTE : Preserve column numbers of '|' character */
		(void) printf(gettext("Track No. |Type    |Start address\n"));
		(void) printf("----------+--------+-------------\n");


		/* look at each track and display it's type. */

		for (p = &toc[4]; p < (toc + toc_size); p += 8) {
			if (p[2] != 0xAA)
				(void) printf(" %-3d      |", p[2]);
			else
				(void) printf("Leadout   |");
			(void) printf("%s   |", (p[1] & 4) ? gettext("Data ") :
			    gettext("Audio"));
			(void) printf("%u\n", read_scsi32(&p[4]));
		}
	}
	(void) printf("\n");
	ret = read_toc(target->d_fd, 1, 0, 12, toc);
	if ((ret == 0) || (toc[1] != 0x0a))
		/* For ATAPI drives or old Toshiba drives */
		ret = read_toc_as_per_8020(target->d_fd, 1, 0, 12, toc);

	if (ret && (toc[1] == 0x0a)) {
		(void) printf(gettext("Last session start address: %u\n"),
		    read_scsi32(&toc[8]));
	}
	free(toc);
	ti = (struct track_info *)my_zalloc(sizeof (struct track_info));

	if (build_track_info(target, -1, ti) && (ti->ti_flags & TI_NWA_VALID)) {
		(void) printf(gettext("Next writable address: %u\n"),
		    ti->ti_nwa);
	}
	free(ti);
	exit(0);
}
Beispiel #16
0
int main(int argc, char **argv) 
{
  iso_primary_descriptor_type  ipd;
  char *dev = default_dev;
  char vendor[9],model[17],rev[5];
  unsigned char reply[1024];
  char tmpstr[255];
  int replylen=sizeof(reply);
  int trackno = 0;
  int info_only = 0;
  unsigned char *buffer;
  int buffersize = READBLOCKS*BLOCKSIZE;
  int start,stop,imagesize=0,tracksize=0;
  int counter = 0;
  long readsize = 0;
  long imagesize_bytes = 0;
  int drive_block_size, init_bsize;
  int force_mode = 0;
  int scanbus_mode = 0;
  int dump_start, dump_count;
  MD5_CTX *MD5; 
  char digest[16],digest_text[33];
  int md5_mode = 0;
  int opt_index = 0;
  int audio_track = 0;
  int readblocksize = BLOCKSIZE;
  int file_format = AF_FILE_AIFFC;
#ifdef IRIX
  CDPARSER *cdp = CDcreateparser();
  CDFRAME  cdframe;
#endif
  int dev_type;
  int i,c,o;
  int len;
  int start_time,cur_time,kbps;

  if (rcsid); 

  MD5 = malloc(sizeof(MD5_CTX));
  buffer=(unsigned char*)malloc(READBLOCKS*AUDIOBLOCKSIZE);
  if (!buffer || !MD5) die("No memory");

  if (argc<2) die("parameter(s) missing\n"
	          "Try '%s --help' for more information.\n",PRGNAME);

 
  /* parse command line parameters */
  while(1) {
    if ((c=getopt_long(argc,argv,"SMmvhid:",long_options,&opt_index))
	== -1) break;
    switch (c) {
    case 'a':
      file_format=AF_FILE_AIFF;
      break;
    case 'A':
      file_format=AF_FILE_AIFFC;
      break;
    case 'v':
      verbose_mode=1;
      break;
    case 'h':
      p_usage();
      break;
    case 'd':
      dev=strdup(optarg);
      break;
    case 't':
      if (sscanf(optarg,"%d",&trackno)!=1) trackno=0;
      break;
    case 'i':
      info_only=1; 
      break;
    case 'c':
      if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2)
	die("invalid parameters");
      dump_mode=1;
      break;
#ifdef IRIX
    case 'C':
      if (sscanf(optarg,"%d,%d",&dump_start,&dump_count)!=2)
	die("invalid parameters");
      dump_mode=2;
      break;
#endif
    case 'f':
      if (sscanf(optarg,"%d",&force_mode)!=1) die("invalid parameters");
      if (force_mode<1 || force_mode >2) {
	die("invalid parameters");
      }
      break;
    case 'm':
      md5_mode=1;
      break;
    case 'M':
      md5_mode=2;
      break;
    case 's':
      audio_mode=1;
      break;
    case 'S':
      scanbus_mode=1;
      break;
    case 'V':
      printf(PRGNAME " "  VERSION "  " HOST_TYPE
	     "\nCopyright (c) Timo Kokkonen, 1997-1998.\n\n"); 
      exit(0);
      break;

    case '?':
      break;

    default:
      die("error parsing parameters");

    }
  }


  if (!info_only) {
    if (md5_mode==2) outfile=fopen("/dev/null","w");
    else outfile=fopen(argv[optind],"w");
    if (!outfile) {
      if (argv[optind]) die("cannot open output file '%s'",argv[optind]);
      info_only=1;
    }
  }

  printf("readiso(9660) " VERSION "\n");

  /* open the scsi device */
  if (scsi_open(dev)) die("error opening scsi device '%s'",dev); 

  if (scanbus_mode) {
    printf("\n");
    scan_bus();
    exit(0);
  }
  
  memset(reply,0,sizeof(reply));
  if ((dev_type=inquiry(vendor,model,rev))<0) 
    die("error accessing scsi device");

  if (verbose_mode) {
    printf("device:   %s\n",dev);
    printf("Vendor:   %s\nModel:    %s\nRevision: %s\n",vendor,model,rev);
  }

  if ( (dev_type&0x1f) != 0x5 ) {
    die("Device doesn't seem to be a CD-ROM!");
  }

#ifdef IRIX
  if (strcmp(vendor,"TOSHIBA")) {
    warn("NOTE! Audio track reading probably not supported on this device.\n");
  }
#endif

  test_ready();
  if (test_ready()!=0) {
    sleep(2);
    if (test_ready()!=0)  die("device not ready");
  }

  fprintf(stderr,"Initializing...\n");
  if (audio_mode) {
#ifdef IRIX
    audioport=ALopenport("readiso","w",0);
    if (!audioport) {
      warn("Cannot initialize audio.");
      audio_mode=0;
    }
#else
    audio_mode=0;
#endif
  }


#ifdef IRIX
  /* Make sure we get sane underflow exception handling */
  sigfpe_[_UNDERFL].repls = _ZERO;
  handle_sigfpes(_ON, _EN_UNDERFL, NULL, _ABORT_ON_ERROR, NULL);
#endif

  /* set_removable(1); */

#if 0
  replylen=255;
  if (mode_sense10(reply,&replylen)==0) {
    printf("replylen=%d blocks=%d blocklen=%d\n",replylen,
	   V3(&reply[8+1]),V3(&reply[8+5]));
    PRINT_BUF(reply,replylen);
  }
  replylen=255; /* sizeof(reply); */
  if (mode_sense(reply,&replylen)==0) {
    printf("replylen=%d blocks=%d blocklen=%d\n",replylen,
	   V3(&reply[4+1]),V3(&reply[4+5]));
    PRINT_BUF(reply,replylen);
  }
#endif

  if (dump_mode==2) init_bsize=AUDIOBLOCKSIZE;
  else init_bsize=BLOCKSIZE;

  start_stop(0);

  if ( (drive_block_size=get_block_size()) < 0 ) {
    warn("cannot get current block size");
    drive_block_size=init_bsize;
  }

  if (drive_block_size != init_bsize) {
    mode_select(init_bsize,(dump_mode==2?0x82:0x00));
    drive_block_size=get_block_size();
    if (drive_block_size!=init_bsize) warn("cannot set drive block size.");
  }

  start_stop(1);

  if (dump_mode && !info_only) {
#ifdef IRIX
    CDFRAME buf;
    if (dump_mode==2) {
      if (cdp) {
	CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0);
      } else die("No audioparser");
    }
#endif
    fprintf(stderr,"Dumping %d sector(s) starting from LBA=%d\n",
	    dump_count,dump_start);
    for (i=dump_start;i<dump_start+dump_count;i++) {
      len=buffersize;
      read_10(i,1,buffer,&len);
      if (len<init_bsize) break;

#ifdef IRIX
      if (dump_mode==2) {
	memcpy(&buf,buffer,CDDA_BLOCKSIZE);
	CDparseframe(cdp,&buf);
      }
#endif
	
      fwrite(buffer,len,1,outfile); 
      fprintf(stderr,".");
    }
    fprintf(stderr,"\ndone.\n");
    
    goto quit;
  }


  fprintf(stderr,"Reading disc TOC...");
  replylen=sizeof(reply);
  read_toc(reply,&replylen,verbose_mode);
  printf("\n");

  if (trackno==0) { /* try to find first data track */
    for (i=0;i<(reply[3]-reply[2]+1);i++) {
      o=4+i*8;
      if (reply[o+1]&DATA_TRACK) { trackno=i+1; break; }
    }
    if (trackno==0) die("No data track(s) found.");
  }

  fprintf(stderr,"Reading track %d...\n",trackno); 

  if ( (trackno < reply[2]) || (trackno > reply[3]) )
    die("Invalid track specified.");
    
  if ( ((reply[(trackno-1)*8+4+1]&DATA_TRACK)==0) ) {
    fprintf(stderr,"Not a data track.\n");
    mode_select(AUDIOBLOCKSIZE,0x82);
    if (mode_sense(reply,&replylen)!=0) die("cannot get sense data");
    drive_block_size=V3(&reply[9]);
    fprintf(stderr,"Selecting CD-DA mode, output file format: %s\n",
	    file_format==AF_FILE_AIFFC?"AIFFC":"AIFF");
    audio_track=1;
  } else {
    audio_track=0;
  }


  start=V4(&reply[(trackno-1)*8+4+4]);
  stop=V4(&reply[(trackno)*8+4+4]);
  tracksize=abs(stop-start);
  /* if (verbose_mode) printf("Start LBA=%d\nStop  LBA=%d\n",start,stop); */

  len=buffersize;
  read_10(start-0,1,buffer,&len);
  /* PRINT_BUF(buffer,32); */

  
  if (!audio_track) {
    /* read the iso9660 primary descriptor */
    fprintf(stderr,"Reading ISO9660 primary descriptor...\n");
    len=buffersize;
    read_10(start+16,1,buffer,&len);
    if (len<sizeof(ipd)) die("cannot read iso9660 primary descriptor.");
    memcpy(&ipd,buffer,sizeof(ipd));
    
    imagesize=ISONUM(ipd.volume_space_size);
    
    /* we should really check here if we really got a valid primary 
       descriptor or not... */
    if ( (imagesize>(stop-start)) || (imagesize<1) ) {
      fprintf(stderr,"\aInvalid ISO primary descriptor!!!\n");
      if (!info_only) fprintf(stderr,"Copying entire track to image file.\n");
      force_mode=2;
    }
    
    if (force_mode==1) {} /* use size from ISO primary descriptor */
    else if (force_mode==2) imagesize=tracksize; /* use size from TOC */
    else {
      if (  ( (tracksize-imagesize) > MAX_DIFF_ALLOWED ) || 
	    ( imagesize > tracksize )  )   {
	fprintf(stderr,"ISO primary descriptor has suspicious volume size"
		" (%d blocks)\n",imagesize);
	imagesize=tracksize;
	fprintf(stderr,
		"Using track size from TOC record (%d blocks) instead.\n", 
		imagesize);
	fprintf(stderr,
		"(option -f can be used to override this behaviour.)\n");
      }
    }

    imagesize_bytes=imagesize*BLOCKSIZE;
    

    if (verbose_mode||info_only) {
      printf("ISO9660 image info:\n");
      printf("Type:              %02xh\n",ipd.type[0]);  
      ISOGETSTR(tmpstr,ipd.id,5);
      printf("ID:                %s\n",tmpstr);
      printf("Version:           %u\n",ipd.version[0]);
      ISOGETSTR(tmpstr,ipd.system_id,32);
      printf("System id:         %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.volume_id,32);
      printf("Volume id:         %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.volume_set_id,128);
      if (strlen(tmpstr)>0) printf("Volume set id:     %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.publisher_id,128);
      if (strlen(tmpstr)>0) printf("Publisher id:      %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.preparer_id,128);
      if (strlen(tmpstr)>0) printf("Preparer id:       %s\n",tmpstr);
      ISOGETSTR(tmpstr,ipd.application_id,128);
      if (strlen(tmpstr)>0) printf("Application id:    %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.creation_date);
      printf("Creation date:     %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.modification_date);
      if (!NULLISODATE(ipd.modification_date)) 
	printf("Modification date: %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.expiration_date);
      if (!NULLISODATE(ipd.expiration_date))
	printf("Expiration date:   %s\n",tmpstr);
      ISOGETDATE(tmpstr,ipd.effective_date);
      if (!NULLISODATE(ipd.effective_date))
	printf("Effective date:    %s\n",tmpstr);
      
      printf("Image size:        %02d:%02d:%02d, %d blocks (%ld bytes)\n",
	      LBA_MIN(ISONUM(ipd.volume_space_size)),
	      LBA_SEC(ISONUM(ipd.volume_space_size)),
	      LBA_FRM(ISONUM(ipd.volume_space_size)),
	      ISONUM(ipd.volume_space_size),
	      (long)ISONUM(ipd.volume_space_size)*BLOCKSIZE
	     );
      printf("Track size:        %02d:%02d:%02d, %d blocks (%ld bytes)\n",
	      LBA_MIN(tracksize),
	      LBA_SEC(tracksize),
	      LBA_FRM(tracksize),
	      tracksize,
	      (long)tracksize*BLOCKSIZE
	     );
    }
  } else { 
#ifdef IRIX
    /* if reading audio track */
    imagesize=tracksize;
    imagesize_bytes=imagesize*CDDA_DATASIZE;
    buffersize = READBLOCKS*AUDIOBLOCKSIZE;
    readblocksize = AUDIOBLOCKSIZE;

    if (cdp) {
      CDaddcallback(cdp, cd_audio, (CDCALLBACKFUNC)playaudio, 0);
    } else die("No audioparser");
    
    fclose(outfile);
    aiffsetup=AFnewfilesetup();
    AFinitrate(aiffsetup,AF_DEFAULT_TRACK,44100.0); /* 44.1 kHz */
    AFinitfilefmt(aiffsetup,file_format);           /* set file format */
    AFinitchannels(aiffsetup,AF_DEFAULT_TRACK,2);   /* stereo */
    AFinitsampfmt(aiffsetup,AF_DEFAULT_TRACK,
		  AF_SAMPFMT_TWOSCOMP,16);          /* 16bit */
    aiffoutfile=AFopenfile(argv[optind],"w",aiffsetup);
    if (!aiffoutfile) die("Cannot open target file (%s).",argv[optind]);
#endif
  }

  /* read the image */

  if (md5_mode) MD5Init(MD5);

  if (!info_only) {
    start_time=(int)time(NULL);
    fprintf(stderr,"Reading %s (%ldMb)...\n",
	    audio_track?"audio track":"ISO9660 image",
	    imagesize_bytes/(1024*1024));

    do {
      len=buffersize;
      if(readsize/readblocksize+READBLOCKS>imagesize) {
	read_10(start+counter,imagesize-readsize/readblocksize,buffer,&len);
      }
      else
	read_10(start+counter,READBLOCKS,buffer,&len);
      if ((counter%(1024*1024/readblocksize))<READBLOCKS) {
	cur_time=(int)time(NULL);
	if ((cur_time-start_time)>0) {
	  kbps=(readsize/1024)/(cur_time-start_time);
	} else {
	  kbps=0;
	}
	
	fprintf(stderr,"%3dM of %dM read. (%d kb/s)         \r",
		counter/512,imagesize/512,kbps);
      }
      counter+=READBLOCKS;
      readsize+=len;
      if (!audio_track) {
	fwrite(buffer,len,1,outfile);
      } else {
#ifdef IRIX
	/* audio track */
	for(i=0;i<(len/CDDA_BLOCKSIZE);i++) {
	  CDparseframe(cdp,(CDFRAME*)&buffer[i*CDDA_BLOCKSIZE]);
	}
#endif
      }
      if (md5_mode) MD5Update(MD5,buffer,(readsize>imagesize_bytes?
				       len-(readsize-imagesize_bytes):len) );
    } while (len==readblocksize*READBLOCKS&&readsize<imagesize*readblocksize);
    
    fprintf(stderr,"\n");
    if (!audio_track) {
      if (readsize > imagesize_bytes) 
	ftruncate(fileno(outfile),imagesize_bytes);
      if (readsize < imagesize_bytes) 
	fprintf(stderr,"Image not complete!\n");
      else fprintf(stderr,"Image complete.\n");
      fclose(outfile);
    } else {
#ifdef IRIX
      AFclosefile(aiffoutfile);
#endif
    }
  }

  if (md5_mode && !info_only) {
    MD5Final((unsigned char*)digest,MD5);
    md2str((unsigned char*)digest,digest_text);
    fprintf(stderr,"MD5 (%s) = %s\n",(md5_mode==2?"'image'":argv[optind]),
	    digest_text);
  }

 quit:
  start_stop(0);
  /* set_removable(1); */

  /* close the scsi device */
  scsi_close();

  return 0;
}
Beispiel #17
0
int
main(int argc, char *argv[])
{    
  int  c, nostop=0;
  char *h;
  int  i_rc = 0;
  cd_operation_t cd_op = NO_OP; /* operation to do in non-interactive mode */
  
  
  psz_program = strrchr(argv[0],'/');
  psz_program = psz_program ? psz_program+1 : argv[0];

  memset(&cddb_opts, 0, sizeof(cddb_opts));
  
  cdio_loglevel_default = CDIO_LOG_WARN;
  /* parse options */
  while ( 1 ) {
    if (-1 == (c = getopt(argc, argv, "acCdehkplL:sSt:vx")))
      break;
    switch (c) {
    case 'v':
      b_verbose = true;
      if (cdio_loglevel_default > CDIO_LOG_INFO) 
        cdio_loglevel_default = CDIO_LOG_INFO;
      break;
    case 'd':
      debug = 1;
      if (cdio_loglevel_default > CDIO_LOG_DEBUG) 
      cdio_loglevel_default = CDIO_LOG_DEBUG;
      break;
    case 'a':
      auto_mode = 1;
      break;

    case 'L':
      i_volume_level = atoi(optarg);
      cd_op = SET_VOLUME;
      b_interactive = false;
      break;

    case 't':
      if (NULL != (h = strchr(optarg,'-'))) {
        *h = 0;
        start_track = atoi(optarg);
        stop_track = atoi(h+1)+1;
        if (0 == start_track) start_track = 1;
        if (1 == stop_track)  stop_track  = CDIO_CDROM_LEADOUT_TRACK;
      } else {
        start_track = atoi(optarg);
        stop_track = start_track+1;
        one_track = 1;
      }
      b_interactive = false;
      cd_op = PLAY_TRACK;
      break;
    case 'p':
      b_interactive = false;
      cd_op = PLAY_CD;
      break;
    case 'l':
      b_interactive = false;
      cd_op = LIST_TRACKS;
      break;
    case 'C':
      b_interactive = false;
      cd_op = CLOSE_CD;
      break;
    case 'c':
      b_interactive = false;
      cd_op = PS_LIST_TRACKS;
      break;
    case 's':
      b_interactive = false;
      cd_op = STOP_PLAYING;
      break;
    case 'S':
      b_interactive = false;
      cd_op = LIST_SUBCHANNEL;
      break;
    case 'e':
      b_interactive = false;
      cd_op = EJECT_CD;
      break;
    case 'k':
      print_keys();
      exit(1);
    case 'h':
      usage(psz_program);
      exit(1);
    default:
      usage(psz_program);
      exit(1);
    }
  }
  
  if (argc > optind) {
    psz_device = strdup(argv[optind]);
  } else {
    char **ppsz_cdda_drives=NULL;
    char **ppsz_all_cd_drives = cdio_get_devices_ret(&driver_id);

    if (!ppsz_all_cd_drives) {
      fprintf(stderr, "Can't find a CD-ROM drive\n");
      exit(2);
    }
    ppsz_cdda_drives = cdio_get_devices_with_cap(ppsz_all_cd_drives, 
                                                 CDIO_FS_AUDIO, false);
    if (!ppsz_cdda_drives || !ppsz_cdda_drives[0]) {
      fprintf(stderr, "Can't find a CD-ROM drive with a CD-DA in it\n");
      exit(3);
    }
    psz_device = strdup(ppsz_cdda_drives[0]);
    cdio_free_device_list(ppsz_all_cd_drives);
    cdio_free_device_list(ppsz_cdda_drives);
  }
  
  if (!b_interactive) {
    b_sig = true;
    nostop=1;
  }

  tty_raw();
  signal(SIGINT,ctrlc);
  signal(SIGQUIT,ctrlc);
  signal(SIGTERM,ctrlc);
  signal(SIGHUP,ctrlc);
  signal(SIGWINCH, sigwinch);

  if (CLOSE_CD != cd_op) {
    /* open device */
    if (b_verbose)
      fprintf(stderr, "open %s... ", psz_device);
    p_cdio = cdio_open (psz_device, driver_id);
    if (!p_cdio && cd_op != EJECT_CD) {
      cd_close(psz_device);
      p_cdio = cdio_open (psz_device, driver_id);
    }
    
    if (p_cdio && b_verbose)
      fprintf(stderr,"ok\n");
  }
  
  if (b_interactive) {
#ifdef HAVE_CDDB
    cddb_log_set_handler (cddb_log_handler);
#else
    ;
#endif
  }  else {
    b_sig = true;
    nostop=1;
    if (EJECT_CD == cd_op) {
      i_rc = cd_eject() ? 0 : 1;
    } else {
      switch (cd_op) {
      case PS_LIST_TRACKS:
      case LIST_TRACKS:
      case PLAY_TRACK:
        read_toc(p_cdio);
      default:
        break;
      }
      if (p_cdio)
        switch (cd_op) {
        case STOP_PLAYING:
          b_cd = true;
          i_rc = cd_stop(p_cdio) ? 0 : 1;
          break;
        case EJECT_CD:
          /* Should have been handled above. */
          cd_eject();
          break;
        case LIST_TRACKS:
          list_tracks();
          break;
        case PS_LIST_TRACKS:
          ps_list_tracks();
          break;

        case PLAY_TRACK:
          /* play just this one track */
          if (b_record) {
            printf("%s / %s\n", artist, title);
            if (one_track)
              printf("%s\n", cd_info[start_track].title);
          }
          i_rc = play_track(start_track, stop_track) ? 0 : 1;
          break;

        case PLAY_CD:
          if (b_record)
            printf("%s / %s\n", artist, title);
          play_track(1,CDIO_CDROM_LEADOUT_TRACK);
          break;

        case SET_VOLUME:
          i_rc = set_volume_level(p_cdio, i_volume_level);
          break;

        case LIST_SUBCHANNEL: 
          if (read_subchannel(p_cdio)) {
            if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
                sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
              {
                printf("track %2d - %02x:%02x (%02x:%02x abs) ",
                       sub.track, sub.rel_addr.m, sub.rel_addr.s,
                       sub.abs_addr.m, sub.abs_addr.s);
              }
            }
            printf("drive state: %s\n", 
                   mmc_audio_state2str(sub.audio_status));
          } else {
            i_rc = 1;
          }
          break;
        case CLOSE_CD: /* Handled below */
        case LIST_KEYS:
        case TOGGLE_PAUSE:
        case EXIT_PROGRAM:
        case NO_OP:
          break;
        }
      else if (CLOSE_CD == cd_op) {
        i_rc = (DRIVER_OP_SUCCESS == cdio_close_tray(psz_device, NULL))
                ? 0 : 1;
      } else {
        fprintf(stderr,"no CD in drive (%s)\n", psz_device);
      }
    }
  }

  /* Play all tracks *unless* we have a play or paused status
     already. */

  read_subchannel(p_cdio);
  if (sub.audio_status != CDIO_MMC_READ_SUB_ST_PAUSED &&
      sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY)
    play_track(1, CDIO_CDROM_LEADOUT_TRACK);

  while ( !b_sig ) {
    int key;
    if (!b_cd) read_toc(p_cdio);
    read_subchannel(p_cdio);
    display_status(false);
    
    if (1 == select_wait(b_cd ? 1 : 5)) {
      switch (key = getch()) {
      case '-':
        decrease_volume_level(p_cdio);
        break;
      case '+':
        increase_volume_level(p_cdio);
        break;
      case 'A':
      case 'a':
        auto_mode = !auto_mode;
        break;
      case 'X':
      case 'x':
        nostop=1;
        /* fall through */
      case 'Q':
      case 'q':
        b_sig = true;
        break;
      case 'E':
      case 'e':
        cd_eject();
        break;
      case 's':
        cd_stop(p_cdio);
        break;
      case 'C':
      case 'c':
        cd_close(psz_device);
        break;
      case 'L':
      case 'l':
        b_all_tracks = !b_all_tracks;
        if (b_all_tracks)
          display_tracks();
        else {
          i_last_display_track = CDIO_INVALID_TRACK;
          display_cdinfo(p_cdio, i_tracks, i_first_track);
        }
        
        break;
      case 'K':
      case 'k':
      case 'h':
      case 'H':
      case '?':
        list_keys();
        break;
      case ' ':
      case 'P':
      case 'p':
        toggle_pause();
        break;
      case KEY_RIGHT:
        if (b_cd &&
            (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
             sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY)) 
          play_track(sub.track+1, CDIO_CDROM_LEADOUT_TRACK);
        else
          play_track(1,CDIO_CDROM_LEADOUT_TRACK);
        break;
      case KEY_LEFT:
        if (b_cd &&
            (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
             sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY))
          play_track(sub.track-1,CDIO_CDROM_LEADOUT_TRACK);
        break;
      case KEY_UP:
        if (b_cd && sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY)
          skip(10);
        break;
      case KEY_DOWN:
        if (b_cd && sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY)
          skip(-10);
        break;
      case '1':
      case '2':
      case '3':
      case '4':
      case '5':
      case '6':
      case '7':
      case '8':
      case '9':
        play_track(key - '0', CDIO_CDROM_LEADOUT_TRACK);
        break;
      case '0':
        play_track(10, CDIO_CDROM_LEADOUT_TRACK);
        break;
      case KEY_F(1):
      case KEY_F(2):
      case KEY_F(3):
      case KEY_F(4):
      case KEY_F(5):
      case KEY_F(6):
      case KEY_F(7):
      case KEY_F(8):
      case KEY_F(9):
      case KEY_F(10):
      case KEY_F(11):
      case KEY_F(12):
      case KEY_F(13):
      case KEY_F(14):
      case KEY_F(15):
      case KEY_F(16):
      case KEY_F(17):
      case KEY_F(18):
      case KEY_F(19):
      case KEY_F(20):
        play_track(key - KEY_F(1) + 11, CDIO_CDROM_LEADOUT_TRACK);
        break;
      }
    }
  }
  if (!nostop) cd_stop(p_cdio);
  tty_restore();
  finish("bye", i_rc);
  
  return 0; /* keep compiler happy */
}
Beispiel #18
0
static void
read_toc (PopplerIndexIter  *index,
          GString          **toc)
{
	if (!index) {
		return;
	}

	if (!*toc) {
		*toc = g_string_new ("");
	}

	do {
		PopplerAction *action;
		PopplerIndexIter *iter;

		action = poppler_index_iter_get_action (index);

		if (!action) {
			continue;
		}

		switch (action->type) {
			case POPPLER_ACTION_GOTO_DEST: {
				PopplerActionGotoDest *ag = (PopplerActionGotoDest *)action;
				PopplerDest *agd = ag->dest;

				if (!tracker_is_empty_string (ag->title)) {
					g_string_append_printf (*toc, "%s ", ag->title);
				}

				if (!tracker_is_empty_string (agd->named_dest)) {
					g_string_append_printf (*toc, "%s ", agd->named_dest);
				}

				break;
			}

			case POPPLER_ACTION_LAUNCH: {
				PopplerActionLaunch *al = (PopplerActionLaunch *)action;

				if (!tracker_is_empty_string (al->title)) {
					g_string_append_printf (*toc, "%s ", al->title);
				}

				if (!tracker_is_empty_string (al->file_name)) {
					g_string_append_printf (*toc, "%s ", al->file_name);
				}

				if (!tracker_is_empty_string (al->params)) {
					g_string_append_printf (*toc, "%s ", al->params);
				}

				break;
			}

			case POPPLER_ACTION_URI: {
				PopplerActionUri *au = (PopplerActionUri *)action;

				if (!tracker_is_empty_string (au->uri)) {
					g_string_append_printf (*toc, "%s ", au->uri);
				}

				break;
			}

			case POPPLER_ACTION_NAMED: {
				PopplerActionNamed *an = (PopplerActionNamed *)action;

				if (!tracker_is_empty_string (an->title)) {
					g_string_append_printf (*toc, "%s, ", an->title);
				}

				if (!tracker_is_empty_string (an->named_dest)) {
					g_string_append_printf (*toc, "%s ", an->named_dest);
				}

				break;
			}

			case POPPLER_ACTION_MOVIE: {
				PopplerActionMovie *am = (PopplerActionMovie *)action;

				if (!tracker_is_empty_string (am->title)) {
					g_string_append_printf (*toc, "%s ", am->title);
				}

				break;
			}

			case POPPLER_ACTION_NONE:
			case POPPLER_ACTION_UNKNOWN:
			case POPPLER_ACTION_GOTO_REMOTE:
			case POPPLER_ACTION_RENDITION:
			case POPPLER_ACTION_OCG_STATE:
			case POPPLER_ACTION_JAVASCRIPT:
				/* Do nothing */
				break;
		}

		poppler_action_free (action);
		iter = poppler_index_iter_get_child (index);
		read_toc (iter, toc);
	} while (poppler_index_iter_next (index));

	poppler_index_iter_free (index);
}