Пример #1
0
static gboolean 
prepare_params (ThreadBurnIsoParams *params, struct burn_drive *drive, gchar **failure_msg)
{
  struct burn_write_opts * burn_options;

  burn_options = burn_write_opts_new (drive);
  burn_write_opts_set_perform_opc (burn_options, 0);
  burn_write_opts_set_multi (burn_options, 0);
  burn_write_opts_set_simulate(burn_options, params->dummy ? 1 : 0);
  burn_write_opts_set_underrun_proof (burn_options, params->burnfree ? 1 : 0);
  /*
   * 32 is the number of blocks to skip. This will increase reliability with BD disks that
   * are used for multisessions. xfburn doesn't support this, but other programs may be using
   * the disc that way, so we respect that here.
   */
  burn_write_opts_set_stream_recording (burn_options, params->stream_recording ? 32 : 0);

  if (!xfburn_set_write_mode (burn_options, params->write_mode, params->disc, WRITE_MODE_TAO)) {
    burn_write_opts_free (burn_options);
    *failure_msg = _("Burn mode is not currently implemented.");
    return FALSE;
  }

  params->burn_options = burn_options;

  params->disc = burn_disc_create ();
  params->session = burn_session_create ();
  params->track = burn_track_create ();

  if (!create_disc (params, failure_msg)) {
    return FALSE;
  }

  return TRUE;
}
Пример #2
0
int telltoc_msinfo(struct burn_drive *drive, 
			int msinfo_explicit, int msinfo_alone)
{
	int ret, lba, nwa = -123456789, aux_lba;
	enum burn_disc_status s;
	struct burn_write_opts *o= NULL;

	s = burn_disc_get_status(drive);
	if (s!=BURN_DISC_APPENDABLE) {
		if (!msinfo_explicit)
			return 2;
		fprintf(stderr,
		   "SORRY: --msinfo can only operate on appendable media.\n");
		return 0;
	}

	/* man mkisofs , option -C :
	   The first number is the sector number of the first sector in
	   the last session of the disk that should be appended to.
	*/
	ret = burn_disc_get_msc1(drive, &lba);
	if (ret <= 0) {
		fprintf(stderr,
			"SORRY: Cannot obtain start address of last session\n");
		{ ret = 0; goto ex; }
	}

	/* man mkisofs , option -C :
	   The second  number is the starting sector number of the new session.
	*/
	/* Set some roughly suitable write opts to be sent to drive. */
	o= burn_write_opts_new(drive);
 	if(o!=NULL) {
   		burn_write_opts_set_perform_opc(o, 0);
   		burn_write_opts_set_write_type(o,
					BURN_WRITE_TAO, BURN_BLOCK_MODE1);
	}
	/* Now try to inquire nwa from drive */
	ret= burn_disc_track_lba_nwa(drive,o,0,&aux_lba,&nwa);
	telltoc_regrab(drive); /* necessary to calm down my NEC drive */
	if(ret<=0) {
		fprintf(stderr,
			"SORRY: Cannot obtain next writeable address\n");
		{ ret = 0; goto ex; }
	}

	if (!msinfo_alone)
		printf("Media msinfo : mkisofs ... -C ");
	printf("%d,%d\n",lba,nwa);
	ret = 1;
ex:;
	if (o != NULL)
		burn_write_opts_free(o);
	return ret;
}
Пример #3
0
int telltoc_media(struct burn_drive *drive)
{
	int ret, media_found = 0, profile_no = -1, num_profiles = 0, i;
	int profiles[64];
	char is_current_profile[64];
	double max_speed = 0.0, min_speed = 0.0, speed_conv;
	off_t available = 0;
	enum burn_disc_status s;
	char profile_name[80], speed_unit[40];
	struct burn_multi_caps *caps = NULL;
	struct burn_write_opts *o = NULL;

	printf("Media current: ");
	ret = burn_disc_get_profile(drive, &profile_no, profile_name);
	if (profile_no > 0 && ret > 0) {
		if (profile_name[0])
			printf("%s\n", profile_name);
		else
			printf("%4.4Xh\n", profile_no);
	} else
		printf("is not recognizable\n");

	/* Determine speed unit before profile_name gets reused */
	speed_conv = 176.4;
	strcpy(speed_unit,"176.4 kB/s  (CD, data speed 150 KiB/s)");
	if (strstr(profile_name, "DVD") == profile_name) {
		speed_conv = 1385.0;
		strcpy(speed_unit,"1385.0 kB/s  (DVD)");
	} else if (strstr(profile_name, "BD") == profile_name) {
                speed_conv = 4495.625;
		strcpy(speed_unit,"4495.625 kB/s  (BD)");
        }

	ret = burn_drive_get_all_profiles(drive, &num_profiles, profiles,
					is_current_profile);
	if (ret > 0) {
		for (i = 0; i < num_profiles; i++) {
			ret = burn_obtain_profile_name(profiles[i],
							profile_name);
			if (ret <= 0)
				sprintf(profile_name,
					"Unknown media type 0x%4.4X",
					(unsigned int) profiles[i]);
			printf("Drive can do : %s%s\n", profile_name,
				is_current_profile[i] ? " (current)" : "");
		}
	}

	printf("Media status : ");
	s = burn_disc_get_status(drive);
	if (s == BURN_DISC_FULL) {
		printf("is written , is closed\n");
		media_found = 1;
	} else if (s == BURN_DISC_APPENDABLE) {
		printf("is written , is appendable\n");
		media_found = 1;
	} else if (s == BURN_DISC_BLANK) {
		printf("is blank\n");
		media_found = 1;
	} else if (s == BURN_DISC_EMPTY)
		printf("is not present\n");
	else
		printf("is not recognizable\n");

	printf("Media reuse  : ");
	if (media_found) {
		if (burn_disc_erasable(drive))
			printf("is erasable\n");
		else
			printf("is not erasable\n");	
	} else
		printf("is not recognizable\n");

	ret = burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
	if (ret > 0) {
		/* Media appears writeable */
		printf("Write multi  : ");
		printf("%s multi-session , ",
			 caps->multi_session == 1 ? "offers" : "cannot do");
		if (caps->multi_track)
			printf("offers multiple tracks\n");
		else
			printf("offers only single track\n");
		printf("Write start  : ");
		if (caps->start_adr == 1)
			printf(
			"offers addresses [%.f , %.f]s , alignment=%.fs\n",
				(double) caps->start_range_low / 2048 ,
				(double) caps->start_range_high / 2048 ,
				(double) caps->start_alignment / 2048 );
		else
			printf("prohibits write start addressing\n");
		printf("Write modes  : ");
		if (caps->might_do_tao)
			printf("TAO%s",
				caps->advised_write_mode == BURN_WRITE_TAO ?
				" (advised)" : "");
		if (caps->might_do_sao)
			printf("%sSAO%s",
				caps->might_do_tao ? " , " : "",
				caps->advised_write_mode == BURN_WRITE_SAO ?
				" (advised)" : "");
		if (caps->might_do_raw)
			printf("%sRAW%s",
				caps->might_do_tao | caps->might_do_sao ?
				" , " : "",
				caps->advised_write_mode == BURN_WRITE_RAW ?
				" (advised)" : "");
		printf("\n");
		printf("Write dummy  : ");
		if (caps->might_simulate)
			printf("supposed to work with non-RAW modes\n");
		else
			printf("will not work\n");
		o= burn_write_opts_new(drive);
		if (o != NULL) {
			burn_write_opts_set_perform_opc(o, 0);
 			if(caps->advised_write_mode == BURN_WRITE_TAO)
   				burn_write_opts_set_write_type(o,
					BURN_WRITE_TAO, BURN_BLOCK_MODE1);
			else if (caps->advised_write_mode == BURN_WRITE_SAO)
				burn_write_opts_set_write_type(o,
					BURN_WRITE_SAO, BURN_BLOCK_SAO);
			else {
				burn_write_opts_free(o);
				o = NULL;
			}
		}
		available = burn_disc_available_space(drive, o);
		printf("Write space  : %.1f MiB  (%.fs)\n",
			((double) available) / 1024.0 / 1024.0,
			((double) available) / 2048.0);
		burn_disc_free_multi_caps(&caps);
		if (o != NULL)
			burn_write_opts_free(o);
	}

	ret = burn_drive_get_write_speed(drive);
	max_speed = ((double ) ret) / speed_conv;
	ret = burn_drive_get_min_write_speed(drive);
	min_speed = ((double ) ret) / speed_conv;
	if (!media_found)
		printf("Drive speed  : max=%.1f  , min=%.1f\n",
			 max_speed, min_speed);
	else
		printf("Avail. speed : max=%.1f  , min=%.1f\n", 
                         max_speed, min_speed);

	ret = 0;
	if (media_found)
		ret = burn_disc_read_atip(drive);
	if(ret>0) {
		ret = burn_drive_get_min_write_speed(drive);
		min_speed = ((double ) ret) / speed_conv;
		ret = burn_drive_get_write_speed(drive);
		max_speed = ((double ) ret) / speed_conv;
		printf("Media speed  : max=%.1f  , min=%.1f\n",
			max_speed, min_speed);
	}
	printf("Speed unit 1x: %s\n", speed_unit);

	if (caps != NULL)
		burn_disc_free_multi_caps(&caps);
	return 1;
}
Пример #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;
}