static gboolean
create_disc (ThreadBurnIsoParams *params, gchar **failure_msg)
{
  gint fd;
  struct stat stbuf;
  off_t fixed_size = 0;
  struct burn_source *data_src;

  gint ret;

  ret = burn_disc_add_session (params->disc, params->session, BURN_POS_END);
  if (ret == 0) {
    g_warning ("Unable to add session to the disc object");
    *failure_msg = _("An error occurred in the burn backend");
    return FALSE;
  }

  burn_track_define_data (params->track, 0, 300*1024, 1, BURN_MODE1);

  fd = open (params->iso_path, O_RDONLY);
  if (fd >= 0)
    if (fstat (fd, &stbuf) != -1)
      if( (stbuf.st_mode & S_IFMT) == S_IFREG)
	fixed_size = stbuf.st_size;

  if (fixed_size == 0) {
    *failure_msg = _("Unable to determine image size.");
    return FALSE;
  }

  data_src = burn_fd_source_new(fd, -1, fixed_size);

  if (data_src == NULL) {
    *failure_msg = _("Cannot open image.");
    return FALSE;
  }

  params->fifo_src = burn_fifo_source_new (data_src, 2048, xfburn_settings_get_int ("fifo-size", FIFO_DEFAULT_SIZE) / 2, 0);
  burn_source_free (data_src);

  if (burn_track_set_source (params->track, params->fifo_src) != BURN_SOURCE_OK) {
    g_warning ("Cannot attach source object to track object");
    *failure_msg = _("An error occurred in the burn backend");
    return FALSE;
  }
  
  burn_session_add_track (params->session, params->track, BURN_POS_END);

  return TRUE;
}
示例#2
0
gboolean
xfburn_transcoder_free_burning_resources (XfburnTranscoder *trans, XfburnAudioTrack *atrack, GError **error)
{
  XfburnTranscoderInterface *iface = XFBURN_TRANSCODER_GET_INTERFACE (trans);

  /* these are part of XfburnAudioTrack, and will be present for all implementations */
  close (atrack->fd);
  burn_source_free (atrack->src);

  /* allow for additional resource deallocation */
  if (iface->free_burning_resources)
    return iface->free_burning_resources (trans, atrack, error);
  
  /* this function is not required by the interface */
  return TRUE;
}
static void
free_params (ThreadBurnIsoParams *params)
{
  if (params->fifo_src)
    burn_source_free (params->fifo_src);

  if (params->burn_options)
    burn_write_opts_free (params->burn_options);

  if (params->track)
    burn_track_free (params->track);

  if (params->session)
    burn_session_free (params->session);

  if (params->disc)
    burn_disc_free (params->disc);

  g_free (params->iso_path);
}
示例#4
0
/** Brings preformatted track images (ISO 9660, audio, ...) onto media.
    To make sure a data image is fully readable on any Linux machine, this
    function adds 300 kiB of padding to the (usualy single) track.
    Audio tracks get padded to complete their last sector.
    A fifo of 4 MB is installed between each track and its data source.
    Each of the 4 MB buffers gets allocated automatically as soon as a track
    begins to be processed and it gets freed as soon as the track is done.
    The fifos do not wait for buffer fill but writing starts immediately.

    In case of external signals expect abort handling of an ongoing burn to
    last up to a minute. Wait the normal burning timespan before any kill -9.
*/
int libburner_payload(struct burn_drive *drive, 
		      char source_adr[][4096], int source_adr_count,
		      int multi, int simulate_burn, int all_tracks_type)
{
	struct burn_source *data_src = NULL, *fifo_src[99];
	struct burn_disc *target_disc = NULL;
	struct burn_session *session = NULL;
	struct burn_write_opts *burn_options = NULL;
	enum burn_disc_status disc_state;
	struct burn_track *track, *tracklist[99];
	struct burn_progress progress;
	time_t start_time;
	int last_sector = 0, padding = 0, trackno, unpredicted_size = 0, fd;
	int fifo_chunksize = 2352, fifo_chunks = 1783; /* ~ 4 MB fifo */
	int ret;
	off_t fixed_size;
	char *adr, reasons[BURN_REASONS_LEN];
	struct stat stbuf;

	for (trackno = 0 ; trackno < source_adr_count; trackno++) {
		fifo_src[trackno] = NULL;
		tracklist[trackno] = NULL;
	}

	if (all_tracks_type != BURN_AUDIO) {
		all_tracks_type = BURN_MODE1;
		/* a padding of 300 kiB helps to avoid the read-ahead bug */
		padding = 300*1024;
		fifo_chunksize = 2048;
		fifo_chunks = 2048; /* 4 MB fifo */
	}

	target_disc = burn_disc_create();
	session = burn_session_create();
	burn_disc_add_session(target_disc, session, BURN_POS_END);

	for (trackno = 0 ; trackno < source_adr_count; trackno++) {
	  tracklist[trackno] = track = burn_track_create();
	  burn_track_define_data(track, 0, padding, 1, all_tracks_type);

	  /* Open file descriptor to source of track data */
	  adr = source_adr[trackno];
	  fixed_size = 0;
	  if (adr[0] == '-' && adr[1] == 0) {
		fd = 0;
	  } else {
		fd = open(adr, O_RDONLY);
		if (fd>=0)
			if (fstat(fd,&stbuf)!=-1)
				if((stbuf.st_mode&S_IFMT)==S_IFREG)
					fixed_size = stbuf.st_size;
	  }
	  if (fixed_size==0)
		unpredicted_size = 1;

	  /* Convert this filedescriptor into a burn_source object */
	  data_src = NULL;
	  if (fd >= 0)
	  	data_src = burn_fd_source_new(fd, -1, fixed_size);
	  if (data_src == NULL) {
		fprintf(stderr,
		       "FATAL: Could not open data source '%s'.\n",adr);
		if(errno!=0)
			fprintf(stderr,"(Most recent system error: %s )\n",
				strerror(errno));
		{ret = 0; goto ex;}
	  }
	  /* Install a fifo object on top of that data source object */
	  fifo_src[trackno] = burn_fifo_source_new(data_src,
					fifo_chunksize, fifo_chunks, 0);
	  if (fifo_src[trackno] == NULL) {
		fprintf(stderr,
			"FATAL: Could not create fifo object of 4 MB\n");
		{ret = 0; goto ex;}
	  }

	  /* Use the fifo object as data source for the track */
	  if (burn_track_set_source(track, fifo_src[trackno])
							 != BURN_SOURCE_OK) {
		fprintf(stderr,
		       "FATAL: Cannot attach source object to track object\n");
		{ret = 0; goto ex;}
	  }

	  burn_session_add_track(session, track, BURN_POS_END);
	  printf("Track %d : source is '%s'\n", trackno+1, adr);

	  /* Give up local reference to the data burn_source object */
	  burn_source_free(data_src);
	  data_src = NULL;
	  
	} /* trackno loop end */

	/* Evaluate drive and media */
	disc_state = burn_disc_get_status(drive);
	if (disc_state != BURN_DISC_BLANK &&
	    disc_state != BURN_DISC_APPENDABLE) {
		if (disc_state == BURN_DISC_FULL) {
			fprintf(stderr, "FATAL: Closed media with data detected. Need blank or appendable media.\n");
			if (burn_disc_erasable(drive))
				fprintf(stderr, "HINT: Try --blank_fast\n\n");
		} else if (disc_state == BURN_DISC_EMPTY) 
			fprintf(stderr,"FATAL: No media detected in drive\n");
		else
			fprintf(stderr,
			 "FATAL: Cannot recognize state of drive and media\n");
		{ret = 0; goto ex;}
	}

	burn_options = burn_write_opts_new(drive);
	burn_write_opts_set_perform_opc(burn_options, 0);
	burn_write_opts_set_multi(burn_options, !!multi);
	if(simulate_burn)
		printf("\n*** Will TRY to SIMULATE burning ***\n\n");
	burn_write_opts_set_simulate(burn_options, simulate_burn);
	burn_drive_set_speed(drive, 0, 0);
	burn_write_opts_set_underrun_proof(burn_options, 1);
	if (burn_write_opts_auto_write_type(burn_options, target_disc,
					reasons, 0) == BURN_WRITE_NONE) {
		fprintf(stderr, "FATAL: Failed to find a suitable write mode with this media.\n");
		fprintf(stderr, "Reasons given:\n%s\n", reasons);
		{ret = 0; goto ex;}
	}
	burn_set_signal_handling("libburner : ", NULL, 0x30);

	printf("Burning starts. With e.g. 4x media expect up to a minute of zero progress.\n");
	start_time = time(0);
	burn_disc_write(burn_options, target_disc);

	while (burn_drive_get_status(drive, NULL) == BURN_DRIVE_SPAWNING)
		usleep(100002);
	while (burn_drive_get_status(drive, &progress) != BURN_DRIVE_IDLE) {
		if (progress.sectors <= 0 ||
		    (progress.sector >= progress.sectors - 1 &&
	             !unpredicted_size) ||
		    (unpredicted_size && progress.sector == last_sector))
			printf(
			     "Thank you for being patient since %d seconds.",
			     (int) (time(0) - start_time));
		else if(unpredicted_size)
			printf("Track %d : sector %d", progress.track+1,
				progress.sector);
		else
			printf("Track %d : sector %d of %d",progress.track+1,
				progress.sector, progress.sectors);
		last_sector = progress.sector;
		if (progress.track >= 0 && progress.track < source_adr_count) {
			int size, free_bytes, ret;
			char *status_text;
	
			ret = burn_fifo_inquire_status(
				fifo_src[progress.track], &size, &free_bytes,
				&status_text);
			if (ret >= 0 ) 
				printf("  [fifo %s, %2d%% fill]", status_text,
					(int) (100.0 - 100.0 *
						((double) free_bytes) /
						(double) size));
		} 
		printf("\n");
		sleep(1);
	}
	printf("\n");

	if (burn_is_aborting(0) > 0)
		{ret = -1; goto ex;}
	if (multi && current_profile != 0x1a && current_profile != 0x13 &&
		current_profile != 0x12 && current_profile != 0x43) 
			/* not with DVD+RW, formatted DVD-RW, DVD-RAM, BD-RE */
		printf("NOTE: Media left appendable.\n");
	if (simulate_burn)
		printf("\n*** Did TRY to SIMULATE burning ***\n\n");
	ret = 1;
ex:;
	/* Dispose objects */
	if (burn_options != NULL)
		burn_write_opts_free(burn_options);
	for (trackno = 0 ; trackno < source_adr_count; trackno++) {
		if (fifo_src[trackno] != NULL)
	  		burn_source_free(fifo_src[trackno]);
		if (tracklist[trackno])
			burn_track_free(tracklist[trackno]);
	}
	if (data_src != NULL)
		burn_source_free(data_src);
	if (session != NULL)
		burn_session_free(session);
	if (target_disc != NULL)
		burn_disc_free(target_disc);
	return ret;
}