diff --git a/cdrskin/cdrskin.1 b/cdrskin/cdrskin.1 index cc34f23..26ddd01 100644 --- a/cdrskin/cdrskin.1 +++ b/cdrskin/cdrskin.1 @@ -580,6 +580,20 @@ contain a "=" character. By default such arguments are seen as misspelled options. It is nevertheless not possible to use one of the options listed with --list_ignored_options. .TP +.BI assert_write_lba= block_number | byte_address +Abort if the write address given with this option is not the same as predicted +immediately before the write session starts. This option can ensure that a +start address which was presumed by a formatter like mkisofs -C is really used +by the drive for writing. +assert_write_lba=0 effectively demands blank media and excludes appendables. +.br +Block numbering is peculiar: If the last character of the option string is +a letter [a-zA-Z] then the usual unit scaling by "s", "k", "m", etc. applies +and the result is divided by 2048. Else the number value of the string is +taken as plain block number with block size 2048 byte. +(E.g ...=1000 or ...=1000s means block 1000, ...=1m means block +512, ...=4096b means block number 2) +.TP .BI \--demand_a_drive Exit with a nonzero value if no drive can be found during a bus scan. .TP diff --git a/cdrskin/cdrskin.c b/cdrskin/cdrskin.c index 73e0a97..1208c59 100644 --- a/cdrskin/cdrskin.c +++ b/cdrskin/cdrskin.c @@ -249,6 +249,7 @@ or #include +#include #include #include #include @@ -1986,6 +1987,8 @@ set_dev:; " --allow_untested_media enable implemented untested media types\n"); printf( " --any_track allow source_addresses to match '^-.' or '='\n"); + printf( + " assert_write_lba= abort if not next write address == lba\n"); printf(" --demand_a_drive exit !=0 on bus scans with empty result\n"); printf(" --devices list accessible devices (tells /dev/...)\n"); printf( @@ -2416,6 +2419,7 @@ struct CdrskiN { int multi; double write_start_address; + int assert_write_lba; int do_eject; char eject_device[Cdrskin_strleN]; @@ -2541,6 +2545,7 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag) o->block_type= BURN_BLOCK_SAO; o->multi= 0; o->write_start_address= -1.0; + o->assert_write_lba= -1; o->burnfree= 1; o->do_eject= 0; o->eject_device[0]= 0; @@ -3498,12 +3503,23 @@ ex:; } +/** Predict address block number where the next write will go to + @param flag Bitfield for control purposes: + bit0= do not return nwa from eventual write_start_address + @return <=0 error, 1 nwa from drive , 2 nwa from write_start_address +*/ int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag) { int ret,lba; struct burn_drive *drive; struct burn_write_opts *o= NULL; + if(skin->write_start_address>=0 && !(flag&1)) { + /* (There is no sense in combining random addressing with audio) */ + *nwa= skin->write_start_address/2048; + return(2); + } + /* Set write opts in order to provoke MODE SELECT. LG GSA-4082B needs it. */ drive= skin->drives[skin->driveno].drive; o= burn_write_opts_new(drive); @@ -4858,6 +4874,18 @@ burn_failed:; #endif /* ! Cdrskin_extra_leaN */ + ret= Cdrskin_obtain_nwa(skin, &nwa,0); + if(ret<=0) + nwa= -1; + if(skin->assert_write_lba>=0 && nwa!=skin->assert_write_lba) { + fprintf(stderr, + "cdrskin: FATAL : Option assert_write_lba= demands block number %10d\n", + skin->assert_write_lba); + fprintf(stderr, + "cdrskin: FATAL : but predicted actual write start address is %10d\n", + nwa); + {ret= 0; goto ex;} + } if(skin->tell_media_space || skin->track_counter<=0) { /* write capacity estimation and return without actual burning */ @@ -4891,11 +4919,8 @@ burn_failed:; #endif /* ! Cdrskin_extra_leaN */ Cdrskin_adjust_speed(skin,0); - if(skin->verbosity>=Cdrskin_verbose_progresS) { - ret= Cdrskin_obtain_nwa(skin, &nwa,0); - if(ret>0) - printf("Starting new track at sector: %d\n",nwa); - } + if(skin->verbosity>=Cdrskin_verbose_progresS && nwa>=0) + printf("Starting new track at sector: %d\n",nwa); skin->drive_is_busy= 1; burn_disc_write(o, disc); if(skin->preskin->abort_handler==-1) @@ -5321,7 +5346,7 @@ sorry_failed_to_eject:; */ int Cdrskin_setup(struct CdrskiN *skin, int argc, char **argv, int flag) { - int i,k,ret,source_has_size=0; + int i,k,l,ret,source_has_size=0; double value,grab_and_wait_value= -1.0; char *cpt,*value_pt,adr[Cdrskin_adrleN],*blank_mode= ""; struct stat stbuf; @@ -5443,6 +5468,14 @@ set_abort_max_wait:; ClN(printf( "cdrskin: --any_track : will accept any unknown option as track source\n")); + } else if(strncmp(argv[i],"assert_write_lba=",17)==0) { + value_pt= argv[i]+17; + value= Scanf_io_size(value_pt,0); + l= strlen(value_pt); + if(l>1) if(isalpha(value_pt[l-1])) + value/= 2048.0; + skin->assert_write_lba= value; + } else if(strcmp(argv[i],"-atip")==0) { if(skin->do_atip<1) skin->do_atip= 1; diff --git a/cdrskin/cdrskin_timestamp.h b/cdrskin/cdrskin_timestamp.h index b84752d..de26adf 100644 --- a/cdrskin/cdrskin_timestamp.h +++ b/cdrskin/cdrskin_timestamp.h @@ -1 +1 @@ -#define Cdrskin_timestamP "2007.03.07.151514" +#define Cdrskin_timestamP "2007.03.09.134622"