New option -as cdrecord emulates a narrow set of cdrecord gestures

This commit is contained in:
2008-02-19 18:45:17 +00:00
parent 4a8f206aa2
commit 08c68166f3
5 changed files with 1064 additions and 68 deletions

View File

@ -18,6 +18,7 @@
#include <string.h>
#include <sys/stat.h>
#include <time.h>
#include <fcntl.h>
/* ------------------------------------------------------------------------ */
@ -547,19 +548,6 @@ int Xorriso_aquire_drive(struct XorrisO *xorriso, char *adr, int flag)
isoburn_ropt_set_default_perms(ropts, (uid_t) 0, (gid_t) 0, (mode_t) 0555);
isoburn_ropt_set_input_charset(ropts, NULL);
#ifdef NIX
memset(&ropts, sizeof(ropts), 0);
ropts.norock= 0;
ropts.nojoliet= 0;
ropts.noiso1999= 1;
ropts.preferjoliet= 0;
ropts.uid= 0;
ropts.gid= 0;
ropts.mode= 0555;
ropts.input_charset= NULL;
ropts.pretend_blank= 0;
#endif /* NIX */
Xorriso_set_image_severities(xorriso, 1); /* No DEBUG messages */
Xorriso_pacifier_reset(xorriso, 0);
isoburn_set_read_pacifier(drive, Xorriso__read_pacifier, (void *) xorriso);
@ -716,13 +704,78 @@ int Xorriso_make_write_options(
}
/* @param flag bit0= do not write but only prepare and return size in sectors
bit1= do not use isoburn wrappers
*/
int Xorriso_sanitize_image_size(struct XorrisO *xorriso,
struct burn_drive *drive, struct burn_disc *disc,
struct burn_write_opts *burn_options, int flag)
{
int ret, img_sectors, num_sessions= 0, num_tracks= 0, padding= 0, profile;
int media_space;
char profile_name[80];
struct burn_session **sessions;
struct burn_track **tracks;
ret= img_sectors= burn_disc_get_sectors(disc);
if(flag&1)
goto ex;
sessions= burn_disc_get_sessions(disc, &num_sessions);
if(sessions==NULL || num_sessions < 1) {
no_track:;
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,"Program error : no track in prepared disc");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
{ret= -1; goto ex;}
}
tracks= burn_session_get_tracks(sessions[0], &num_tracks);
if(tracks==NULL || num_tracks < 1)
goto no_track;
padding= 0;
ret= burn_disc_get_profile(drive, &profile, profile_name);
padding= xorriso->padding / 2048;
if(xorriso->padding > padding * 2048)
padding++;
if(img_sectors>0 && (profile==0x09 || profile==0x0a)) { /* CD-R , CD-RW */
if(img_sectors + padding < Xorriso_cd_min_track_sizE) {
padding= Xorriso_cd_min_track_sizE - img_sectors;
sprintf(xorriso->info_text,
"Expanded track to minimum size of %d sectors",
Xorriso_cd_min_track_sizE);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
}
burn_track_define_data(tracks[0], 0, padding * 2048, 0, BURN_MODE1);
Xorriso_process_msg_queues(xorriso,0);
if(flag&2)
media_space= burn_disc_available_space(drive, burn_options) /
(off_t) 2048;
else
media_space= isoburn_disc_available_space(drive, burn_options) /
(off_t) 2048;
if(media_space < img_sectors + padding) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,"Image size %ds exceeds free space on media %ds",
img_sectors + padding, media_space);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
{ret= 0; goto ex;}
}
ret= 1;
ex:;
return(ret);
}
/* @param flag bit0= do not write but only prepare and return size in sectors
*/
int Xorriso_write_session(struct XorrisO *xorriso, int flag)
{
int ret, media_space, img_sectors, padding= 0, profile= 0, relax= 0, i;
int ret, relax= 0, i;
int major, minor, micro;
char profile_name[80], xorriso_id[256], *img_id;
char xorriso_id[256], *img_id;
struct isoburn_imgen_opts *sopts= NULL;
struct burn_drive_info *dinfo, *source_dinfo;
struct burn_drive *drive, *source_drive;
@ -736,6 +789,11 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
IsoImage *image = NULL;
ElToritoBootImage *bootimg;
#ifdef NIX
char profile_name[80];
int padding= 0, img_sectors, media_space, profile;
#endif
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to write", 2);
if(ret<=0)
@ -794,7 +852,6 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
}
isoburn_igopt_set_level(sopts, 2);
isoburn_igopt_set_extensions(sopts, 1|((!!xorriso->do_joliet)<<1));
isoburn_igopt_set_relaxed(sopts, isoburn_igopt_allow_deep_paths);
@ -804,33 +861,6 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
isoburn_igopt_set_out_charset(sopts, NULL);
isoburn_igopt_set_fifo_size(sopts, xorriso->fs * 2048);
#ifdef NIX
memset(&sopts, 0, sizeof(sopts));
sopts.level= 2;
sopts.rockridge= 1;
sopts.joliet= !!xorriso->do_joliet;
sopts.iso1999= 0;
sopts.omit_version_numbers= 0;
sopts.allow_deep_paths= 1;
sopts.allow_longer_paths= 0;
sopts.max_37_char_filenames= 0;
sopts.no_force_dots= 0;
sopts.allow_lowercase= 0;
sopts.allow_full_ascii= 0;
sopts.joliet_longer_paths= 0;
sopts.sort_files= 1;
sopts.replace_dir_mode= 2*!!xorriso->do_global_mode;
sopts.dir_mode= xorriso->global_dir_mode;
sopts.replace_file_mode= 2*!!xorriso->do_global_mode;
sopts.file_mode= xorriso->global_file_mode;
sopts.replace_uid= 2*!!xorriso->do_global_uid;
sopts.uid= xorriso->global_uid;
sopts.replace_gid= 2*!!xorriso->do_global_gid;
sopts.gid= xorriso->global_gid;
sopts.output_charset= NULL;
sopts.fifo_size= xorriso->fs * 2048;
#endif /* NIX */
if(image!=NULL &&
strlen(Xorriso_program_versioN)+strlen(Xorriso_timestamP)<80) {
sprintf(xorriso_id, "XORRISO-%s %s",
@ -882,6 +912,18 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag)
if(ret<=0)
goto ex;
#ifndef NIX
ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, flag&1);
if(ret<=0) {
isoburn_cancel_prepared_write(source_drive, drive, 0);
goto ex;
}
if(flag&1)
goto ex;
#else
ret= img_sectors= burn_disc_get_sectors(disc);
if(flag&1)
goto ex;
@ -926,6 +968,8 @@ no_track:;
{ret= 0; goto ex;}
}
#endif /* NIX */
xorriso->run_state= 1; /* Indicate that burning has started */
isoburn_disc_write(burn_options, disc);
burn_write_opts_free(burn_options);
@ -1041,8 +1085,11 @@ int Xorriso_pacifier_loop(struct XorrisO *xorriso, struct burn_drive *drive,
break;
current_time= Sfile_microtime(0);
if(drive_status == BURN_DRIVE_WRITING && progress.sectors > 0) {
sprintf(xorriso->info_text, "Writing: sector %d of %d",
progress.sector, progress.sectors);
if(progress.sector<=progress.sectors)
sprintf(xorriso->info_text, "Writing: sector %d of %d",
progress.sector, progress.sectors);
else
sprintf(xorriso->info_text, "Writing: sector %d", progress.sector);
ret= isoburn_get_fifo_status(drive, &size, &free_bytes, &status_text);
if(ret>0 )
sprintf(xorriso->info_text+strlen(xorriso->info_text),
@ -1823,17 +1870,6 @@ int Xorriso_process_msg_queues(struct XorrisO *xorriso, int flag)
error_code==0x3feb9 || error_code==0x3feb2)
strcpy(severity, "MISHAP");
#ifdef NIX
/* ??? throw this out already yet and rely on above libburn workaround ?*/
/* <<< SORRY messages during burn run get mapped to MISHAP
should not be necessary with libisofs-0.6.4 */
if(pass+tunneled==0 && xorriso->run_state==1 &&
strcmp(severity, "SORRY")==0) {
fprintf(stderr, "xorriso_DEBUG: %s %X\n", severity, error_code);
strcpy(severity, "MISHAP"); /* image generation severity */
}
#endif
Xorriso_msgs_submit(xorriso, error_code, xorriso->info_text, os_errno,
severity, ((pass+tunneled)+1)<<2);
count++;
@ -3797,3 +3833,271 @@ int Xorriso_report_lib_versions(struct XorrisO *xorriso, int flag)
return(1);
}
/* @param flag bit0= -inq
bit1= -checkdrive
*/
int Xorriso_atip(struct XorrisO *xorriso, int flag)
{
int ret, profile_number= 0;
char *respt, profile_name[80];
double x_speed_max, x_speed_min= -1.0;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
enum burn_disc_status s;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to print drive and media info", 2);
if(ret<=0)
return(0);
respt= xorriso->result_line;
sprintf(respt, "Device type :");
ret= burn_drive_get_drive_role(drive);
if(ret==0)
sprintf(respt+strlen(respt), "%s\n", "Emulated (null-drive)");
else if(ret==2)
sprintf(respt+strlen(respt), "%s\n",
"Emulated (stdio-drive, 2k random read-write)");
else if(ret==3)
sprintf(respt+strlen(respt), "%s\n",
"Emulated (stdio-drive, sequential write-only)");
else if(ret!=1)
sprintf(respt+strlen(respt), "%s\n","Emulated (stdio-drive)");
else
sprintf(respt+strlen(respt), "%s\n","Removable CD-ROM");
sprintf(respt+strlen(respt), "Vendor_info : '%s'\n",dinfo->vendor);
sprintf(respt+strlen(respt), "Identifikation : '%s'\n",dinfo->product);
sprintf(respt+strlen(respt), "Revision : '%s'\n",dinfo->revision);
Xorriso_result(xorriso,1);
if(flag&1)
return(1);
sprintf(respt, "Driver flags : BURNFREE\n");
sprintf(respt+strlen(respt), "Supported modes: SAO TAO\n");
Xorriso_result(xorriso,1);
if(flag&2)
return(1);
s= burn_disc_get_status(drive);
ret= burn_disc_get_profile(drive,&profile_number,profile_name);
if(ret<=0) {
profile_number= 0;
strcpy(profile_name, "-unidentified-");
}
if(s != BURN_DISC_UNSUITABLE) {
ret= burn_disc_read_atip(drive);
if(ret>0) {
ret= burn_drive_get_min_write_speed(drive);
x_speed_min= ((double) ret)/176.4;
}
}
if(s==BURN_DISC_EMPTY) {
sprintf(respt, "Current: none\n");
Xorriso_result(xorriso,1);
return(1);
} else
sprintf(respt, "Current: %s\n",profile_name);
Xorriso_result(xorriso,1);
if(strstr(profile_name,"DVD")==profile_name) {
sprintf(respt, "book type: %s (emulated booktype)\n", profile_name);
Xorriso_result(xorriso,1);
sprintf(respt, "xorriso: message for sdvdbackup: \"(growisofs mode Restricted Overwrite)\"\n");
Xorriso_result(xorriso,1);
} else {
sprintf(respt, "ATIP info from disk:\n");
Xorriso_result(xorriso,1);
if(burn_disc_erasable(drive))
sprintf(respt, " Is erasable\n");
else
sprintf(respt, " Is not erasable\n");
Xorriso_result(xorriso,1);
{ int start_lba,end_lba,min,sec,fr;
ret= burn_drive_get_start_end_lba(drive,&start_lba,&end_lba,0);
if(ret>0) {
burn_lba_to_msf(start_lba,&min,&sec,&fr);
sprintf(respt, " ATIP start of lead in: %d (%-2.2d:%-2.2d/%-2.2d)\n",
start_lba,min,sec,fr);
Xorriso_result(xorriso,1);
burn_lba_to_msf(end_lba,&min,&sec,&fr);
sprintf(respt, " ATIP start of lead out: %d (%-2.2d:%-2.2d/%-2.2d)\n",
end_lba,min,sec,fr);
Xorriso_result(xorriso,1);
}
}
ret= burn_drive_get_write_speed(drive);
x_speed_max= ((double) ret)/176.4;
if(x_speed_min<0)
x_speed_min= x_speed_max;
sprintf(respt,
" 1T speed low: %.f 1T speed high: %.f\n",x_speed_min,x_speed_max);
Xorriso_result(xorriso,1);
}
return(1);
}
int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag)
{
int ret, fd, unpredicted_size;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
struct burn_write_opts *burn_options;
struct burn_disc *disc= NULL;
struct burn_session *session;
struct burn_track *track;
struct stat stbuf;
off_t fixed_size= 0;
struct burn_source *data_src, *fifo_src;
enum burn_disc_status disc_state;
char reasons[BURN_REASONS_LEN], sfe[5*SfileadrL];
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to burn track", 2);
if(ret<=0)
return(0);
ret= Xorriso_make_write_options(xorriso, drive, &burn_options, 0);
if(ret<=0)
goto ex;
disc= burn_disc_create();
session= burn_session_create();
ret= burn_disc_add_session(disc,session,BURN_POS_END);
if(ret==0) {
/* >>> */;
goto ex;
}
track= burn_track_create();
if(track_source[0] == '-' && track_source[1] == 0) {
fd= 0;
} else {
fd= open(track_source, 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;
data_src= NULL;
if(fd>=0)
data_src= burn_fd_source_new(fd, -1, fixed_size);
if(data_src==NULL) {
sprintf(xorriso->info_text, "Could not open data source %s",
Text_shellsafe(track_source,sfe,0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
fifo_src= burn_fifo_source_new(data_src, 2048, xorriso->fs, 0);
if(fifo_src == NULL) {
sprintf(xorriso->info_text, "Could not create fifo object of 4 MB");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
ret= 0; goto ex;
}
if(burn_track_set_source(track, fifo_src)!=BURN_SOURCE_OK) {
sprintf(xorriso->info_text,
"Cannot attach source object to track object");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FATAL", 0);
ret= 0; goto ex;
}
burn_session_add_track(session, track, BURN_POS_END);
burn_source_free(data_src);
disc_state = burn_disc_get_status(drive);
if(disc_state == BURN_DISC_BLANK) {
/* ok */;
} else if(disc_state == BURN_DISC_APPENDABLE) {
if(!isoburn_needs_emulation(drive)) {
sprintf(xorriso->info_text,
"Appendable media with data detected. Need blank media.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
if(disc_state == BURN_DISC_FULL) {
sprintf(xorriso->info_text,
"Closed media with data detected. Need blank media.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
if(burn_disc_erasable(drive)) {
sprintf(xorriso->info_text, "Try --blank_fast\n");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "HINT", 0);
}
} else if(disc_state == BURN_DISC_EMPTY) {
sprintf(xorriso->info_text, "No media detected in drive");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
} else {
sprintf(xorriso->info_text,
"Cannot recognize state of drive and media");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
}
ret= 0; goto ex;
}
if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) ==
BURN_WRITE_NONE) {
sprintf(xorriso->info_text,
"Failed to find a suitable write mode with this media.\n");
sprintf(xorriso->info_text+strlen(xorriso->info_text),
"Reasons given:\n%s", reasons);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(isoburn_needs_emulation(drive))
burn_write_opts_set_start_byte(burn_options, (off_t) 0);
ret= Xorriso_sanitize_image_size(xorriso, drive, disc, burn_options, 2);
if(ret<=0)
goto ex;
xorriso->run_state= 1; /* Indicate that burning has started */
burn_disc_write(burn_options, disc);
ret= Xorriso_pacifier_loop(xorriso, drive, 0);
if(ret<=0)
goto ex;
if(!burn_drive_wrote_well(drive)) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"libburn indicates failure with writing.");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
sprintf(xorriso->info_text, "Writing completed sucessfully.\n\n");
Xorriso_info(xorriso, 0);
ret= 1;
ex:;
Xorriso_process_msg_queues(xorriso,0);
if(disc!=NULL)
burn_disc_free(disc);
xorriso->run_state= 0; /* Indicate that burning has ended */
return(ret);
}
/* @param flag bit1= outdev rather than indev
@return <0 error, 0 = no profile to see , 1= ok , 2= ok, is CD profile
*/
int Xorriso_get_profile(struct XorrisO *xorriso, int *profile_number,
char profile_name[80], int flag)
{
int ret;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
*profile_number= 0;
profile_name[0]= 0;
if(xorriso->out_drive_handle==NULL)
return(0);
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to determine media type", flag&2);
if(ret<=0)
return(0);
ret=burn_disc_get_profile(drive, profile_number, profile_name);
if(ret<=0)
return(ret);
if(*profile_number==0x08 || *profile_number==0x09 || *profile_number==0x0a)
return(2);
return(0);
}