From 06bcc637d6c80319e7f7ef548dfa915592589468 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Sat, 12 Jul 2008 18:48:15 +0000 Subject: [PATCH] New options --grow_overwriteable_iso and write_start_address= with -as cdrecord --- xorriso/xorriso.1 | 6 +- xorriso/xorriso.c | 50 ++++++++++------- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 106 ++++++++++++++++++++++++++++++------ xorriso/xorrisoburn.h | 6 +- 5 files changed, 132 insertions(+), 38 deletions(-) diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 37a477f9..9e2e4017 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH XORRISO 1 "Jul, 10, 2008" +.TH XORRISO 1 "Jul, 12, 2008" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -2146,6 +2146,10 @@ Follow-up sessions are written like this: \fB$\fR xorriso -as mkisofs -M /dev/sr0 -C $m prepared_for_iso/tree2 | \\ .br xorriso -as cdrecord -v dev=/dev/sr0 -multi -eject - +.br +Always eject the drive tray between sessions. The old sessions +get read via stdio:/dev/sr0 and thus are prone to device driver +peculiarities. .SS .B Let xorriso work underneath growisofs growisofs expects an ISO formatter program which understands options -o, -C, diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 6564d317..ad53669e 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -7069,10 +7069,11 @@ int Xorriso_reaquire_outdev(struct XorrisO *xorriso, int flag) int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv, int flag) { - int ret, i, k, mem_do_close, aq_ret, eject_ret, msc1, msc2; + int ret, i, k, mem_do_close, aq_ret, eject_ret, msc1, msc2, hflag; int do_atip= 0, do_checkdrive= 0, do_eject= 0, do_scanbus= 0; int do_toc= 0, do_verbous= 0, do_version= 0, do_help= 0, do_waiti= 0; - int do_multi= 0, do_msinfo= 0; + int do_multi= 0, do_msinfo= 0, do_grow= 0; + double write_start_address= -1.0; char track_source[SfileadrL], sfe[5*SfileadrL], dev_adr[SfileadrL], *cpt; char mem_report_about_text[80], *report_about= "SORRY", blank_mode[80]; char speed[80]; @@ -7088,7 +7089,7 @@ int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv, "drive_scsi_dev_family=", "fallback_program=", "modesty_on_drive=", "tao_to_sao_tsize=", - "direct_write_amount=", "write_start_address=", "msifile=", + "direct_write_amount=", "msifile=", "tsize=", @@ -7141,11 +7142,12 @@ int Xorriso_cdrskin(struct XorrisO *xorriso, char *whom, int argc, char **argv, "\t-data\t\tSubsequent tracks are CD-ROM data mode 1 (default)", "\t-pad\t\tpadsize=30k", "\t-nopad\t\tDo not pad", +"\t--grow_overwriteable_iso\temulate multi-session on DVD+RW", +"\twrite_start_address=#\t\twrite to given byte address on DVD+RW", "\t-help\t\tprint this text to stderr and exit emulation", "Actually this is the integrated ISO RockRidge filesystem manipulator xorriso", -"lending its libburn capabilities to a very limited cdrecord emulation.", -"Only a single data track can be burnt to blank or overwriteable media which", -"will be finalized afterwards if possible.", +"lending its libburn capabilities to a very limited cdrecord emulation. Only", +"a single data track can be burnt to blank, appendable or overwriteable media.", "A much more elaborate cdrecord emulator is cdrskin from the same project.", "@End_of_helptexT@" }; @@ -7308,17 +7310,23 @@ no_volunteer:; do_toc= 1; } else if(strcmp(argv[i], "--grow_overwriteable_iso")==0) { -/* >>> MULTI : allow --grow_overwriteable_iso */ - +/* MULTI : allow --grow_overwriteable_iso */ +/* sprintf(xorriso->info_text, "-as %s: Option --grow_overwriteable_iso not supported.", whom); Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); ret= 0; goto ex; +*/ -/* >>> MULTI : allow write_start_address= */ -/* >>> MULTI : combine write_start_address=32 with --grow_overwriteable_iso */ -/* >>> MULTI : ??? how about cdrskin. shouldn't it combine too ? */ + do_grow= 1; + } else if(strncmp(argv[i], "write_start_address=", 20)==0) { + +/* MULTI : allow write_start_address= */ + write_start_address= Scanf_io_size(argv[i]+20,0); + +/* ??? >>> MULTI : combine write_start_address=32 with --grow_overwriteable_iso */ +/* ??? >>> MULTI : ??? how about cdrskin. shouldn't it combine too ? */ } else if(strcmp(argv[i], "-v")==0 || strcmp(argv[i],"-verbose")==0) { do_verbous++; @@ -7376,12 +7384,14 @@ no_volunteer:; } if(dev_adr[0]) { - /* >>> MULTI : + /* MULTI : if grow_overwriteable_iso : consider overwriteables with ISO as appendable */ - /* bit3= overwriteables as blank */ + hflag= 2|32; + if(!do_grow) + hflag|= 8; /* consider overwriteables as blank */ - ret= Xorriso_option_dev(xorriso, dev_adr, 2|8|32); + ret= Xorriso_option_dev(xorriso, dev_adr, hflag); if(ret<=0) goto ex; } @@ -7420,7 +7430,7 @@ no_volunteer:; /* MULTI : perform -msinfo */ if(do_msinfo) { - ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 2); + ret= Xorriso_msinfo(xorriso, &msc1, &msc2, 2 | !!do_grow); if(ret<=0) goto ex; sprintf(xorriso->result_line, "%d,%d\n", msc1, msc2); @@ -7472,7 +7482,8 @@ no_volunteer:; /* MULTI : do not close if -multi */ xorriso->do_close= !do_multi; - ret= Xorriso_burn_track(xorriso, track_source, 0); + ret= Xorriso_burn_track(xorriso, (off_t) write_start_address, + track_source, !!do_grow); aq_ret= Xorriso_reaquire_outdev(xorriso, 2*(ret>0)); if(ret<=0 && ret=argc) goto not_enough_args; i++; - strcpy(indev, "stdio:"); + if(strncmp(argv[i], "stdio:", 6)!=0) + strcpy(indev, "stdio:"); if(Sfile_str(indev+strlen(indev), argv[i], 0)<=0) {ret= -1; goto ex;} } else if(strcmp(argv[i], "-C")==0 || @@ -9874,7 +9886,7 @@ int Xorriso_option_grow_blindly(struct XorrisO *xorriso, char *msc2, int flag) double num; int l; - if(msc2[0]==0 || strcmp(msc2,"-")==0 || strcmp(msc2, "off")==0) { + if(msc2[0]==0 || msc2[0]=='-' || strcmp(msc2, "off")==0) { xorriso->grow_blindly_msc2= -1; return(1); } diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index 7ea07a52..31a00468 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.07.12.181846" +#define Xorriso_timestamP "2008.07.12.184833" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 26a54aef..3f229b5a 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -956,10 +956,8 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) if(ret<0) {ret= 0; goto ex;} Xorriso_set_abort_severity(xorriso, 1); - if(xorriso->out_drive_handle == xorriso->in_drive_handle || - xorriso->in_drive_handle == NULL) { - ret= isoburn_prepare_disc(source_drive, &disc, sopts); - } else if (xorriso->grow_blindly_msc2 >= 0) { + if (xorriso->grow_blindly_msc2 >= 0 && + xorriso->out_drive_handle != xorriso->in_drive_handle) { ret= isoburn_prepare_blind_grow(source_drive, &disc, sopts, drive, xorriso->grow_blindly_msc2); if(ret>0) { @@ -969,6 +967,9 @@ int Xorriso_write_session(struct XorrisO *xorriso, int flag) if(ret<=0) goto ex; } + } else if(xorriso->out_drive_handle == xorriso->in_drive_handle || + xorriso->in_drive_handle == NULL) { + ret= isoburn_prepare_disc(source_drive, &disc, sopts); } else { ret= isoburn_prepare_new_image(source_drive, &disc, sopts, drive); } @@ -5935,9 +5936,14 @@ int Xorriso_atip(struct XorrisO *xorriso, int flag) } -int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) +/* @param write_start_address is valid if >=0 + @param flag bit0= grow_overwriteable_iso +*/ +int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address, + char *track_source, int flag) { - int ret, fd, unpredicted_size, profile_number, is_cd= 0; + int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1; + int isosize= -1, i, full_size; struct burn_drive_info *dinfo; struct burn_drive *drive; struct burn_write_opts *burn_options; @@ -5949,6 +5955,7 @@ int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) struct burn_source *data_src, *fifo_src; enum burn_disc_status disc_state; char reasons[BURN_REASONS_LEN], sfe[5*SfileadrL], profile_name[80]; + char buffer[64*1024], *headpt; ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive, @@ -6006,12 +6013,14 @@ int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) burn_session_add_track(session, track, BURN_POS_END); burn_source_free(data_src); - /* >>> MULTI : + /* MULTI : if grow_overwriteable_iso: consider overwriteables with ISO as appendable */ - - disc_state = burn_disc_get_status(drive); + if(flag&1) + disc_state = isoburn_disc_get_status(drive); + else + disc_state = burn_disc_get_status(drive); if(disc_state == BURN_DISC_BLANK) { /* ok */; } else if(disc_state == BURN_DISC_APPENDABLE) { @@ -6049,6 +6058,8 @@ int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) } ret= 0; goto ex; } + if(isoburn_needs_emulation(drive)) + burn_write_opts_set_multi(burn_options, 0); if(burn_write_opts_auto_write_type(burn_options, disc, reasons, 0) == BURN_WRITE_NONE) { sprintf(xorriso->info_text, @@ -6062,11 +6073,36 @@ int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) ret= Xorriso_get_profile(xorriso, &profile_number, profile_name, 2); is_cd= (ret==2); - /* >>> MULTI : - consider overwriteables as blank if not grow_overwriteable_iso*/ + /* MULTI : + consider overwriteables as blank if not grow_overwriteable_iso */ + + if(isoburn_needs_emulation(drive)) { + if(flag&1) { + ret= isoburn_disc_track_lba_nwa(drive, burn_options, 0, &dummy, &nwa); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot obtain next writeable address of emulated multi-session media\n"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + if(nwa==32) + nwa= 0; /* No automatic toc emulation. Formatter might not be aware. */ + burn_write_opts_set_start_byte(burn_options,((off_t) nwa) * (off_t) 2048); + } else { + nwa= 0; + burn_write_opts_set_start_byte(burn_options, (off_t) 0); + } + } + + /* MULTI : */ + if(write_start_address>=0) { + nwa= write_start_address / (off_t) 2048; + if(((off_t) nwa) * (off_t) 2048 < write_start_address ) + nwa++; + burn_write_opts_set_start_byte(burn_options, ((off_t) nwa) * (off_t) 2048); + } - 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; @@ -6085,6 +6121,39 @@ int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag) ret= 0; goto ex; } + /* MULTI : */ + /* update ISO header at lba 0 */ + if((flag&1) && nwa >= 32) { + if(isosize>0) { + + /* >>> MULTI : copy memorized stream header from -isosize into buffer */; + + } else { + ret= isoburn_read_iso_head(drive, nwa, &isosize, buffer, 2); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot read freshly written ISO image head"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + /* patch ISO header */ + full_size= nwa + isosize; + headpt= buffer + 32*1024; + for(i=0;i<4;i++) + headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff; + ret= burn_random_access_write(drive, (off_t) 0, buffer, + (off_t) (64*1024), 1); + if(ret<=0) { + Xorriso_process_msg_queues(xorriso,0); + sprintf(xorriso->info_text, + "Cannot write new ISO image head to LBA 0"); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + ret= 0; goto ex; + } + } + sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n", Text_shellsafe(xorriso->outdev,sfe,0)); Xorriso_info(xorriso, 0); @@ -6397,7 +6466,8 @@ int Xorriso_libburn_adr(struct XorrisO *xorriso, char *path, char adr[], /* MULTI : */ -/* @param flag bit1= obtain info from outdev +/* @param flag bit0= grow_overwriteable_iso + bit1= obtain info from outdev */ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag) { @@ -6410,10 +6480,14 @@ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag) "on attempt to obtain msinfo", flag&2); if(ret<=0) return(ret); - /* >>> if grow_overwriteable_iso : + /* MULTI: + if grow_overwriteable_iso : inquire by isoburn_disc_get_status() */; - disc_state = burn_disc_get_status(drive); + if(flag&1) + disc_state= isoburn_disc_get_status(drive); + else + disc_state= burn_disc_get_status(drive); if(disc_state != BURN_DISC_APPENDABLE) { Xorriso_process_msg_queues(xorriso,0); sprintf(xorriso->info_text, diff --git a/xorriso/xorrisoburn.h b/xorriso/xorrisoburn.h index 8294a6b0..5a05aa64 100644 --- a/xorriso/xorrisoburn.h +++ b/xorriso/xorrisoburn.h @@ -188,7 +188,11 @@ int Xorriso_iso_lstat(struct XorrisO *xorriso, char *path, struct stat *stbuf, */ int Xorriso_atip(struct XorrisO *xorriso, int flag); -int Xorriso_burn_track(struct XorrisO *xorriso, char *track_source, int flag); +/* @param write_start_address is valid if >=0 + @param flag bit0= grow_overwriteable_iso +*/ +int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address, + char *track_source, int flag); /* @param flag bit1= outdev rather than indev @return <=0 = failure , 1= ok , 2= ok, is CD profile