New cdrskin option --grow_overwriteable_iso

This commit is contained in:
Thomas Schmitt 2007-08-26 20:09:47 +00:00
parent dcf35bd556
commit 53634f23de
5 changed files with 439 additions and 52 deletions

View File

@ -79,6 +79,7 @@ struct CdrfifO {
/* eventual ISO-9660 image size obtained from first 64k of input */ /* eventual ISO-9660 image size obtained from first 64k of input */
double iso_fs_size; double iso_fs_size;
char *iso_fs_descr; /* eventually block 16 to 31 of input */
/* (sequential) fd chaining */ /* (sequential) fd chaining */
/* fds: 0=source, 1=dest */ /* fds: 0=source, 1=dest */
@ -162,6 +163,7 @@ int Cdrfifo_new(struct CdrfifO **ff, int source_fd, int dest_fd,
o->empty_counter= 0.0; o->empty_counter= 0.0;
o->full_counter= 0.0; o->full_counter= 0.0;
o->iso_fs_size= -1.0; o->iso_fs_size= -1.0;
o->iso_fs_descr= NULL;
for(i= 0; i<Cdrfifo_ffd_maX; i++) { for(i= 0; i<Cdrfifo_ffd_maX; i++) {
o->follow_up_fds[i][0]= o->follow_up_fds[i][1]= -1; o->follow_up_fds[i][0]= o->follow_up_fds[i][1]= -1;
o->follow_up_eop[i]= o->follow_up_sod[i]= -1; o->follow_up_eop[i]= o->follow_up_sod[i]= -1;
@ -222,6 +224,8 @@ int Cdrfifo_destroy(struct CdrfifO **ff, int flag)
/* eventual closing of source fds is the job of the calling application */ /* eventual closing of source fds is the job of the calling application */
if(o->iso_fs_descr!=NULL)
free((char *) o->iso_fs_descr);
if(o->buffer!=NULL) if(o->buffer!=NULL)
free((char *) o->buffer); free((char *) o->buffer);
free((char *) o); free((char *) o);
@ -400,6 +404,14 @@ int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes, int flag)
} }
int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag)
{
*pt= o->iso_fs_descr;
o->iso_fs_descr= NULL;
return(*pt!=NULL);
}
/** Get counters which are mentioned by cdrecord at the end of burning. /** Get counters which are mentioned by cdrecord at the end of burning.
It still has to be examined wether they mean what i believe they do. It still has to be examined wether they mean what i believe they do.
*/ */
@ -882,19 +894,24 @@ int Cdrfifo_fill(struct CdrfifO *o, int size, int flag)
} }
#ifndef Cdrfifo_standalonE #ifndef Cdrfifo_standalonE
{ int Scan_for_iso_size(unsigned char data[2048], double *size_in_bytes, if(fill>=32*2048) {
int Scan_for_iso_size(unsigned char data[2048], double *size_in_bytes,
int flag); int flag);
int i; int bs= 16*2048;
double size; double size;
/* try to obtain an ISO-9660 file system size */ /* memorize blocks 16 to 31 */
for(i= 0; i<32*2048 && i+2048<=fill; i+=2048) { if(o->iso_fs_descr!=NULL)
ret= Scan_for_iso_size((unsigned char *) (o->buffer+i), &size, 0); free((char *) o->iso_fs_descr);
if(ret<=0) o->iso_fs_descr= TSOB_FELD(char,bs);
continue; if(o->iso_fs_descr==NULL)
return(-1);
memcpy(o->iso_fs_descr,o->buffer+bs,bs);
/* try to obtain ISO-9660 file system size from block 16 */
ret= Scan_for_iso_size((unsigned char *) (o->buffer+bs), &size, 0);
if(ret>0)
o->iso_fs_size= size; o->iso_fs_size= size;
break;
}
} }
#endif #endif

View File

@ -123,6 +123,16 @@ int Cdrfifo_get_cdr_counters(struct CdrfifO *o,
int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag); int Cdrfifo_get_iso_fs_size(struct CdrfifO *o, double *size_in_bytes,int flag);
/** Take over the eventually memorized blocks 16 to 31 of input (2 kB each).
The fifo forgets the blocks by this call. I.e. a second one will return 0.
After this call it is the responsibility of the caller to dispose the
retrieved memory via call free().
@param pt Will be filled either with NULL or a pointer to 32 kB of data
@return 0=nothing is buffered, 1=pt points to valid freeable data
*/
int Cdrfifo_adopt_iso_fs_descr(struct CdrfifO *o, char **pt, int flag);
/** Check for pending data at the fifo's source file descriptor and wether the /** Check for pending data at the fifo's source file descriptor and wether the
fifo is ready to take them. Simultaneously check the buffer for existing fifo is ready to take them. Simultaneously check the buffer for existing
data and the destination fd for readiness to accept some. If so, a small data and the destination fd for readiness to accept some. If so, a small

View File

@ -2,7 +2,7 @@
.\" First parameter, NAME, should be all caps .\" First parameter, NAME, should be all caps
.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
.\" other parameters are allowed: see man(7), man(1) .\" other parameters are allowed: see man(7), man(1)
.TH CDRSKIN 1 "August 12, 2007" .TH CDRSKIN 1 "August 26, 2007"
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" Some roff macros, for reference:
@ -202,8 +202,13 @@ Currently types DVD+RW, DVD-RW and DVD-RAM can be overwritten via cdrskin.
.br .br
DVD+RW and DVD-RAM media get treated as blank media regardless wether they DVD+RW and DVD-RAM media get treated as blank media regardless wether they
hold data or not. They need no special initial formatting. hold data or not. They need no special initial formatting.
Options -audio and -multi are not allowed. Only one track is allowed. Option -audio is not allowed. Only one track is allowed.
-toc does not return information about the media content. Option -multi cannot mark a recognizeable end of overwriteable media.
Therefore -multi is banned unless ISO-9660 images shall be expandable by help
of option --grow_overwriteable_iso.
Without this option or without an ISO-9660 filesystem image present
on media, -toc does not return information about the media content.
.br
Currently there is no difference between -sao and -tao. If ever, then -tao Currently there is no difference between -sao and -tao. If ever, then -tao
will be the mode which preserves the current behavior. will be the mode which preserves the current behavior.
.br .br
@ -451,6 +456,9 @@ The result string shall be used as argument of option -C with said programs.
It gives the start address of the most recent session and the predicted It gives the start address of the most recent session and the predicted
start address of the next session to be appended. The string is empty if start address of the next session to be appended. The string is empty if
the most recent session was not written with option -multi. the most recent session was not written with option -multi.
.br
To have a chance for working on overwriteable media, this option has to be
accompanied by option --grow_overwriteable_iso.
.TP .TP
.BI \-multi .BI \-multi
This option keeps the CD or unformatted DVD-R[W] appendable after the current This option keeps the CD or unformatted DVD-R[W] appendable after the current
@ -459,9 +467,14 @@ Without it the disc gets closed and may not be written any more - unless it
is a -RW and gets blanked which causes loss of its content. is a -RW and gets blanked which causes loss of its content.
.br .br
The following sessions can only be written in -tao mode. -multi is prohibited The following sessions can only be written in -tao mode. -multi is prohibited
with overwriteable DVD media and with DVD-R[W] DAO write mode. with DVD-R[W] DAO write mode. Option --prodvd_cli_compatible eventually makes
Option --prodvd_cli_compatible eventually makes -multi tolerable but cannot -multi tolerable but cannot make it work.
make it work. .br
With overwriteable DVD media, -multi cannot mark the end of the session.
So when adding a new session this end has to be determined from the payload.
Currently only ISO-9660 filesystems can be used that way. See option
.B \--grow_overwriteable_iso
for lifting the ban on -multi.
.br .br
In order to have all filesystem content accessible, the eventual ISO-9660 In order to have all filesystem content accessible, the eventual ISO-9660
filesystem of a follow-up filesystem of a follow-up
@ -686,6 +699,36 @@ the software protection against buffer underun is as weak as the size of
fifo_start_at= . So it is best if the drive offers hardware protection which fifo_start_at= . So it is best if the drive offers hardware protection which
is enabled automatically if not driveropts=noburnfree is given. is enabled automatically if not driveropts=noburnfree is given.
.TP .TP
.BI \--grow_overwriteable_iso
Enable emulation of multi-session writing on overwriteable media which
contain an ISO-9660 filesystem. This emulation is learned from growisofs -M
but adapted to the usage model of
.br
.B cdrskin -msinfo ; mkisofs -C -M | cdrskin [-multi] -
.br
--grow_overwriteable_iso does not hamper the use of true multi-session media.
It demands nevertheless that the track source is a ISO-9660 filesystem image.
With overwriteable media and no option blank=fast|all present it expands an
eventual ISO-9660 filesystem. It is assumed that this image's inner size
description points to the end of the valuable data on media.
.br
Options -msinfo and -toc will then work for overwriteables. -toc will always
show a single session with its size increasing with every added mkisofs image.
.br
--grow_overwriteable_iso causes option blank=fast|all to invalidate an
eventual ISO-9660 image by altering the first few bytes of block 16 on
overwriteable media.
.br
If not overriden by option write_start_address=, the track with the new image
will be placed at the end of the old one. One may use option assert_write_lba=
to make sure that media state and mkisofs job do match.
.br
Note: The equivalent of growisofs -Z is
.br
(mkisofs | cdrskin --grow_overwriteable_iso blank=fast [-multi])
.br
growisofs -dvd-compat is roughly equivalent to cdrskin without option -multi.
.TP
.BI \--list_ignored_options .BI \--list_ignored_options
List all ignored cdrecord options. The "-" options cannot be used as addresses List all ignored cdrecord options. The "-" options cannot be used as addresses
of track sources. No track source address may begin with a text equal to an of track sources. No track source address may begin with a text equal to an

View File

@ -132,7 +132,7 @@ or
Move them down to Cdrskin_libburn_from_pykix_svN on version leap Move them down to Cdrskin_libburn_from_pykix_svN on version leap
*/ */
#define Cdrskin_libburn_has_random_access_writE 1 #define Cdrskin_libburn_has_random_access_rW 1
#endif /* Cdrskin_libburn_0_3_9 */ #endif /* Cdrskin_libburn_0_3_9 */
@ -561,7 +561,8 @@ int Sfile_home_adr_s(char *filename, char *fileadr, int fa_size, int flag)
#endif /* ! Cdrskin_extra_leaN */ #endif /* ! Cdrskin_extra_leaN */
/* <<< Preliminary sketch : to go into libburn later */ /* This would rather belong to libisofs */
/* Learned from reading growisofs.c , /* Learned from reading growisofs.c ,
watching mkisofs, and viewing its results via od -c */ watching mkisofs, and viewing its results via od -c */
/* @return 0=no size found , 1=*size_in_bytes is valid */ /* @return 0=no size found , 1=*size_in_bytes is valid */
@ -580,6 +581,20 @@ int Scan_for_iso_size(unsigned char data[2048], double *size_in_bytes,
} }
int Set_descr_iso_size(unsigned char data[2048], double size_in_bytes,
int flag)
{
unsigned int sectors, i;
sectors= size_in_bytes/2048.0;
if(size_in_bytes>((double) sectors) * 2048.0)
sectors++;
for(i=0;i<4;i++)
data[87-i]= data[80+i]= (sectors >> (8*i)) & 0xff;
return(1);
}
/* --------------------------------------------------------------------- */ /* --------------------------------------------------------------------- */
/** Address translation table for users/applications which do not look /** Address translation table for users/applications which do not look
@ -800,6 +815,7 @@ struct CdrtracK {
/** Eventually detected data image size */ /** Eventually detected data image size */
double data_image_size; double data_image_size;
char *iso_fs_descr; /* eventually block 16 to 31 of input during detection */
/** Wether to demand a detected data image size and use it (or else abort) */ /** Wether to demand a detected data image size and use it (or else abort) */
int use_data_image_size; /* 0=no, 1=size not defined yet, 2=size defined */ int use_data_image_size; /* 0=no, 1=size not defined yet, 2=size defined */
@ -872,6 +888,7 @@ int Cdrtrack_new(struct CdrtracK **track, struct CdrskiN *boss,
o->track_type_by_default= 1; o->track_type_by_default= 1;
o->swap_audio_bytes= 0; o->swap_audio_bytes= 0;
o->data_image_size= -1.0; o->data_image_size= -1.0;
o->iso_fs_descr= NULL;
o->use_data_image_size= 0; o->use_data_image_size= 0;
o->extracting_container= 0; o->extracting_container= 0;
o->fifo_enabled= 0; o->fifo_enabled= 0;
@ -923,6 +940,8 @@ int Cdrtrack_destroy(struct CdrtracK **o, int flag)
if(track->libburn_track!=NULL) if(track->libburn_track!=NULL)
burn_track_free(track->libburn_track); burn_track_free(track->libburn_track);
if(track->iso_fs_descr!=NULL)
free((char *) track->iso_fs_descr);
free((char *) track); free((char *) track);
*o= NULL; *o= NULL;
return(1); return(1);
@ -982,6 +1001,15 @@ int Cdrtrack_get_size(struct CdrtracK *track, double *size, double *padding,
} }
int Cdrtrack_get_iso_fs_descr(struct CdrtracK *track,
char **descr, double *size, int flag)
{
*descr= track->iso_fs_descr;
*size= track->data_image_size;
return(*descr != NULL && *size > 0.0);
}
int Cdrtrack_get_source_path(struct CdrtracK *track, int Cdrtrack_get_source_path(struct CdrtracK *track,
char **source_path, int *source_fd, int *is_from_stdin, int flag) char **source_path, int *source_fd, int *is_from_stdin, int flag)
{ {
@ -1122,15 +1150,26 @@ int Cdrtrack_seek_isosize(struct CdrtracK *track, int fd, int flag)
return(0); return(0);
if((stbuf.st_mode&S_IFMT)!=S_IFREG && (stbuf.st_mode&S_IFMT)!=S_IFBLK) if((stbuf.st_mode&S_IFMT)!=S_IFREG && (stbuf.st_mode&S_IFMT)!=S_IFBLK)
return(2); return(2);
if(track->iso_fs_descr!=NULL)
free((char *) track->iso_fs_descr);
track->iso_fs_descr= TSOB_FELD(char,16*2048);
if(track->iso_fs_descr==NULL)
return(-1);
for(i=0;i<32 && track->data_image_size<=0;i++) { for(i=0;i<32 && track->data_image_size<=0;i++) {
for(got= 0; got<2048;got+= ret) { for(got= 0; got<2048;got+= ret) {
ret= read(fd, secbuf+got, 2048-got); ret= read(fd, secbuf+got, 2048-got);
if(ret<=0) if(ret<=0)
return(0); return(0);
} }
if(i<16)
continue;
memcpy(track->iso_fs_descr+(i-16)*2048,secbuf,2048);
if(i>16)
continue;
ret= Scan_for_iso_size((unsigned char *) secbuf, &size, 0); ret= Scan_for_iso_size((unsigned char *) secbuf, &size, 0);
if(ret<=0) if(ret<=0)
continue; break;
track->data_image_size= size; track->data_image_size= size;
if(track->use_data_image_size) { if(track->use_data_image_size) {
Cdrtrack_activate_image_size(track,&size,1); Cdrtrack_activate_image_size(track,&size,1);
@ -1379,6 +1418,9 @@ int Cdrtrack_fill_fifo(struct CdrtracK *track, int fifo_start_at, int flag)
ret= Cdrfifo_get_iso_fs_size(track->fifo,&data_image_size,0); ret= Cdrfifo_get_iso_fs_size(track->fifo,&data_image_size,0);
if(ret>0) if(ret>0)
track->data_image_size= data_image_size; track->data_image_size= data_image_size;
if(track->iso_fs_descr!=NULL)
free((char *) track->iso_fs_descr);
Cdrfifo_adopt_iso_fs_descr(track->fifo,&(track->iso_fs_descr),0);
return(1); return(1);
} }
@ -2770,9 +2812,23 @@ struct CdrskiN {
double tao_to_sao_tsize; double tao_to_sao_tsize;
int stdin_source_used; int stdin_source_used;
/* For option -isosize */ /* Info about media capabilities */
int media_does_multi;
int media_is_overwriteable;
/* For option -isosize and --grow_overwriteable_iso */
int use_data_image_size; int use_data_image_size;
/* For growisofs stunt :
0=disabled,
1=do stunt, fabricate toc, allow multi,
2=overwriteable_iso_head is valid
3=initial session (mostly to appease -multi on overwriteables)
*/
int grow_overwriteable_iso;
/* New image head buffer for --grow_overwriteable_iso */
char overwriteable_iso_head[32*2048]; /* block 0 to 31 of target */
}; };
int Cdrskin_destroy(struct CdrskiN **o, int flag); int Cdrskin_destroy(struct CdrskiN **o, int flag);
@ -2869,6 +2925,11 @@ int Cdrskin_new(struct CdrskiN **skin, struct CdrpreskiN *preskin, int flag)
o->tao_to_sao_tsize= 0.0; o->tao_to_sao_tsize= 0.0;
o->stdin_source_used= 0; o->stdin_source_used= 0;
o->use_data_image_size= 0; o->use_data_image_size= 0;
o->media_does_multi= 0;
o->media_is_overwriteable= 0;
o->grow_overwriteable_iso= 0;
memset(o->overwriteable_iso_head,0,sizeof(o->overwriteable_iso_head));
#ifndef Cdrskin_extra_leaN #ifndef Cdrskin_extra_leaN
ret= Cdradrtrn_new(&(o->adr_trn),0); ret= Cdradrtrn_new(&(o->adr_trn),0);
@ -3072,6 +3133,25 @@ int Cdrskin_adjust_speed(struct CdrskiN *skin, int flag)
} }
int Cdrskin_determine_media_caps(struct CdrskiN *skin, int flag)
{
#ifdef Cdrskin_libburn_has_get_multi_capS
int ret;
struct burn_multi_caps *caps = NULL;
skin->media_is_overwriteable= skin->media_does_multi= 0;
ret= burn_disc_get_multi_caps(skin->grabbed_drive,BURN_WRITE_NONE,&caps,0);
if(ret<=0)
return(0);
skin->media_is_overwriteable= !!caps->start_adr;
skin->media_does_multi= !!caps->multi_session;
return(1);
#else /* Cdrskin_libburn_has_get_multi_capS */
return(-1);
#endif
}
/** Obtain access to a libburn drive for writing or information retrieval. /** Obtain access to a libburn drive for writing or information retrieval.
If libburn is not restricted to a single persistent address then the If libburn is not restricted to a single persistent address then the
unused drives are dropped. This might be done by shutting down and unused drives are dropped. This might be done by shutting down and
@ -3209,6 +3289,7 @@ int Cdrskin_grab_drive(struct CdrskiN *skin, int flag)
} }
} }
#endif /* Cdrskin_libburn_has_get_profilE */ #endif /* Cdrskin_libburn_has_get_profilE */
Cdrskin_determine_media_caps(skin,0);
ret= 1; ret= 1;
ex:; ex:;
@ -3870,6 +3951,77 @@ int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag)
} }
/** Read and buffer the start of an existing ISO-9660 image from
overwriteable target media.
*/
int Cdrskin_overwriteable_iso_size(struct CdrskiN *skin, int *size, int flag)
{
#ifdef Cdrskin_libburn_has_random_access_rW
int ret;
off_t data_count= 0;
double size_in_bytes;
char *buf;
buf= skin->overwriteable_iso_head;
if(!skin->media_is_overwriteable)
{ret= 0; goto ex;}
/* Read first 64 kB */
ret= burn_read_data(skin->grabbed_drive,(off_t) 0,buf,32*2048,&data_count,0);
if(ret<=0)
{ret= 0; goto ex;}
ret= Scan_for_iso_size((unsigned char *) (buf+16*2048), &size_in_bytes,0);
if(ret<=0) {
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: No detectable ISO-9660 size on media\n"));
{ret= 0; goto ex;}
}
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: detected ISO-9660 size : %.f (%fs)\n",
size_in_bytes, size_in_bytes/2048.0));
if(size_in_bytes/2048.0>2147483647-1-16) {
fprintf(stderr,
"cdrskin: FATAL : ISO-9660 filesystem in terabyte size detected\n");
{ret= 0; goto ex;}
}
*size= size_in_bytes/2048.0;
if(size_in_bytes-((double) *size)*2048.0>0.0)
(*size)++;
if((*size)%16)
*size+= 16-((*size)%16);
skin->grow_overwriteable_iso= 2;
ret= 1;
ex:;
return(ret);
#else /* Cdrskin_libburn_has_random_access_rW */
return(-1);
#endif
}
int Cdrskin_invalidate_iso_head(struct CdrskiN *skin, int flag)
{
int ret;
int size;
fprintf(stderr,
"cdrskin: blank=... : invalidating ISO-9660 head on overwriteable media\n");
ret= Cdrskin_overwriteable_iso_size(skin,&size,0);
if(ret<=0) {
fprintf(stderr,
"cdrskin: NOTE : Not an ISO-9660 file system. Left unaltered.\n");
return(2);
}
skin->overwriteable_iso_head[16*2048]= 0;
skin->overwriteable_iso_head[16*2048+3]=
skin->overwriteable_iso_head[16*2048+4]= 'x';
ret= burn_random_access_write(skin->grabbed_drive,(off_t) 16*2048,
skin->overwriteable_iso_head+16*2048,
(off_t) 16*2048,1);
return(ret);
}
/** Perform -toc under control of Cdrskin_atip(). /** Perform -toc under control of Cdrskin_atip().
@param flag Bitfield for control purposes: @param flag Bitfield for control purposes:
bit0= do not list sessions separately (do it cdrecord style) bit0= do not list sessions separately (do it cdrecord style)
@ -3878,7 +4030,7 @@ int Cdrskin_obtain_nwa(struct CdrskiN *skin, int *nwa, int flag)
int Cdrskin_toc(struct CdrskiN *skin, int flag) int Cdrskin_toc(struct CdrskiN *skin, int flag)
{ {
int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0; int num_sessions= 0,num_tracks= 0,lba= 0,track_count= 0,total_tracks= 0;
int session_no, track_no, pmin, psec, pframe; int session_no, track_no, pmin, psec, pframe, ret;
struct burn_drive *drive; struct burn_drive *drive;
struct burn_disc *disc= NULL; struct burn_disc *disc= NULL;
struct burn_session **sessions; struct burn_session **sessions;
@ -3888,8 +4040,23 @@ int Cdrskin_toc(struct CdrskiN *skin, int flag)
drive= skin->drives[skin->driveno].drive; drive= skin->drives[skin->driveno].drive;
disc= burn_drive_get_disc(drive); disc= burn_drive_get_disc(drive);
if(disc==NULL) if(disc==NULL) {
if(skin->grow_overwriteable_iso>0) {
ret= Cdrskin_overwriteable_iso_size(skin,&lba,0);
if(ret>0) {
printf(
"first: 1 last 1 (fabricated from ISO-9660 image on overwriteable media)\n");
printf(
"track: 1 lba: 0 ( 0) 00:02:00 adr: 1 control: 4 mode: 1\n");
burn_lba_to_msf(lba, &pmin, &psec, &pframe);
printf("track:lout lba: %9d (%9d) %2.2d:%2.2d:%2.2d",
lba,4*lba,pmin,psec,pframe);
printf(" adr: 1 control: 4 mode: -1\n");
return(1);
}
}
goto cannot_read; goto cannot_read;
}
sessions= burn_disc_get_sessions(disc,&num_sessions); sessions= burn_disc_get_sessions(disc,&num_sessions);
if(flag&1) { if(flag&1) {
for(session_no= 0; session_no<num_sessions; session_no++) { for(session_no= 0; session_no<num_sessions; session_no++) {
@ -4315,7 +4482,7 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
"cdrskin: NOTE : blank=format_... : media is already formatted\n"); "cdrskin: NOTE : blank=format_... : media is already formatted\n");
fprintf(stderr, fprintf(stderr,
"cdrskin: HINT : If you really want to re-format, add option -force\n"); "cdrskin: HINT : If you really want to re-format, add option -force\n");
return(2); {ret= 2; goto ex;}
} }
} else if(profile_number == 0x1a) { /* DVD+RW */ } else if(profile_number == 0x1a) { /* DVD+RW */
if(!((skin->blank_format_type>>8)&4)) { if(!((skin->blank_format_type>>8)&4)) {
@ -4323,12 +4490,12 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
"cdrskin: NOTE : blank=format_... : DVD+RW do not need this\n"); "cdrskin: NOTE : blank=format_... : DVD+RW do not need this\n");
fprintf(stderr, fprintf(stderr,
"cdrskin: HINT : For de-icing use option blank=format_overwrite_full"); "cdrskin: HINT : For de-icing use option blank=format_overwrite_full");
return(2); {ret= 2; goto ex;}
} }
} else { } else {
fprintf(stderr, fprintf(stderr,
"cdrskin: SORRY : blank=%s for now does DVD+/-RW only\n",fmt_text); "cdrskin: SORRY : blank=%s for now does DVD+/-RW only\n",fmt_text);
return(0); {ret= 0; goto ex;}
} }
if(s==BURN_DISC_UNSUITABLE) if(s==BURN_DISC_UNSUITABLE)
fprintf(stderr, fprintf(stderr,
@ -4338,7 +4505,18 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
} else if(do_format==0) { } else if(do_format==0) {
/* Classical blanking of erasable media */ /* Classical blanking of erasable media */
if(s!=BURN_DISC_FULL && if(skin->grow_overwriteable_iso > 0 && skin->media_is_overwriteable) {
if(skin->dummy_mode) {
fprintf(stderr,
"cdrskin: would have begun to pseudo-blank disc if not in -dummy mode\n");
goto blanking_done;
}
skin->grow_overwriteable_iso= 3;
ret= Cdrskin_invalidate_iso_head(skin, 0);
if(ret<=0)
goto ex;
goto blanking_done;
} else if(s!=BURN_DISC_FULL &&
(s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable) && (s!=BURN_DISC_APPENDABLE || skin->no_blank_appendable) &&
(profile_number!=0x13 || !skin->prodvd_cli_compatible) && (profile_number!=0x13 || !skin->prodvd_cli_compatible) &&
(s!=BURN_DISC_BLANK || !skin->force_is_set)) { (s!=BURN_DISC_BLANK || !skin->force_is_set)) {
@ -4346,7 +4524,7 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
if(s==BURN_DISC_BLANK) { if(s==BURN_DISC_BLANK) {
fprintf(stderr, fprintf(stderr,
"cdrskin: NOTE : blank=... : media was already blank (and still is)\n"); "cdrskin: NOTE : blank=... : media was already blank (and still is)\n");
return(2); {ret= 2; goto ex;}
} else if(s==BURN_DISC_APPENDABLE) { } else if(s==BURN_DISC_APPENDABLE) {
fprintf(stderr, fprintf(stderr,
"cdrskin: FATAL : blank=... : media is still appendable\n"); "cdrskin: FATAL : blank=... : media is still appendable\n");
@ -4357,11 +4535,11 @@ int Cdrskin_blank(struct CdrskiN *skin, int flag)
fprintf(stderr, fprintf(stderr,
"cdrskin: HINT : If you are certain to have a CD-RW, try option -force\n"); "cdrskin: HINT : If you are certain to have a CD-RW, try option -force\n");
} }
return(0); {ret= 0; goto ex;}
} }
if(!burn_disc_erasable(drive)) { if(!burn_disc_erasable(drive)) {
fprintf(stderr,"cdrskin: FATAL : blank=... : media is not erasable\n"); fprintf(stderr,"cdrskin: FATAL : blank=... : media is not erasable\n");
return(0); {ret= 0; goto ex;}
} }
if((profile_number == 0x14 || profile_number == 0x13) && if((profile_number == 0x14 || profile_number == 0x13) &&
!skin->prodvd_cli_compatible) !skin->prodvd_cli_compatible)
@ -4372,7 +4550,7 @@ unsupported_format_type:;
fprintf(stderr, fprintf(stderr,
"cdrskin: SORRY : blank=%s is unsupported with media type %s\n", "cdrskin: SORRY : blank=%s is unsupported with media type %s\n",
fmt_text, profile_name); fmt_text, profile_name);
return(0); {ret= 0; goto ex;}
} }
if(skin->dummy_mode) { if(skin->dummy_mode) {
@ -4843,7 +5021,7 @@ int Cdrskin_activate_write_mode(struct CdrskiN *skin, enum burn_disc_status s,
int ok, was_still_default= 0, block_type_demand,track_type,sector_size, i; int ok, was_still_default= 0, block_type_demand,track_type,sector_size, i;
int profile_number= -1, track_type_1= 0, mixed_mode= 0, unpredicted_size= 0; int profile_number= -1, track_type_1= 0, mixed_mode= 0, unpredicted_size= 0;
int might_do_tao= 0, might_do_sao= 1, allows_multi= 1, ret, current_is_cd= 1; int might_do_tao= 0, might_do_sao= 1, allows_multi= 1, ret, current_is_cd= 1;
int use_data_image_size; int use_data_image_size, current_is_overwriteable= 0;
struct burn_drive_info *drive_info = NULL; struct burn_drive_info *drive_info = NULL;
char profile_name[80]; char profile_name[80];
double fixed_size= 0.0, tao_to_sao_tsize= 0.0, dummy; double fixed_size= 0.0, tao_to_sao_tsize= 0.0, dummy;
@ -5024,19 +5202,27 @@ check_with_drive:;
#ifdef Cdrskin_libburn_has_get_multi_capS #ifdef Cdrskin_libburn_has_get_multi_capS
ret = burn_disc_get_multi_caps(skin->grabbed_drive,skin->write_type,&caps,0); ret = burn_disc_get_multi_caps(skin->grabbed_drive,skin->write_type,&caps,0);
if (ret>0) if (ret>0) {
allows_multi= caps->multi_session; current_is_overwriteable= caps->start_adr;
allows_multi= caps->multi_session || current_is_overwriteable;
}
burn_disc_free_multi_caps(&caps); burn_disc_free_multi_caps(&caps);
#endif #endif
if(skin->multi && !allows_multi) { if(skin->multi) {
if(skin->prodvd_cli_compatible) { if(!allows_multi) {
skin->multi= 0; if(skin->prodvd_cli_compatible) {
if(skin->verbosity>=Cdrskin_verbose_progresS) skin->multi= 0;
fprintf(stderr, "cdrskin: NOTE : Ignored option -multi.\n"); if(skin->verbosity>=Cdrskin_verbose_progresS)
} else { fprintf(stderr, "cdrskin: NOTE : Ignored option -multi.\n");
fprintf(stderr, } else {
fprintf(stderr,
"cdrskin: SORRY : Cannot keep this media appendable after write by -multi\n"); "cdrskin: SORRY : Cannot keep this media appendable after write by -multi\n");
return(0); return(0);
} else if(current_is_overwriteable) {
skin->multi= 0;
if(!skin->use_data_image_size)
if(skin->verbosity>=Cdrskin_verbose_progresS)
fprintf(stderr, "cdrskin: NOTE : -multi cannot leave a recognizeable end mark on this media.\n");
} }
} }
@ -5122,7 +5308,7 @@ int Cdrskin_announce_tracks(struct CdrskiN *skin, int flag)
#endif /* ! Cdrskin_extra_leaN */ #endif /* ! Cdrskin_extra_leaN */
#ifdef Cdrskin_libburn_has_random_access_writE #ifdef Cdrskin_libburn_has_random_access_rW
int Cdrskin_direct_write(struct CdrskiN *skin, int flag) int Cdrskin_direct_write(struct CdrskiN *skin, int flag)
{ {
@ -5238,7 +5424,75 @@ ex:;
return(ret); return(ret);
} }
#endif /* Cdrskin_libburn_has_random_access_writE */
int Cdrskin_grow_overwriteable_iso(struct CdrskiN *skin, int flag)
{
int ret, i, went_well= 1;
char *track_descr,*td,*md;
double track_size, media_size;
ret= Cdrtrack_get_iso_fs_descr(skin->tracklist[0],&track_descr,&track_size,0);
if(ret<=0) {
fprintf(stderr,"cdrskin: SORRY : Saw no ISO-9660 filesystem in track 0\n");
return(ret);
}
if(skin->grow_overwriteable_iso==3) /* initial session */
return(1);
if(skin->grow_overwriteable_iso!=2) {
fprintf(stderr,
"cdrskin: SORRY : Could not read ISO-9660 descriptors from media\n");
return(0);
}
ret= Scan_for_iso_size((unsigned char *) skin->overwriteable_iso_head+16*2048,
&media_size, 0);
if(ret<=0) {
fprintf(stderr,"cdrskin: SORRY : No recognizable ISO-9660 on media\n");
return(0);
}
/* Write new sum into media descr 0 */
md= skin->overwriteable_iso_head+16*2048;
memcpy(md,track_descr,2048);
Set_descr_iso_size((unsigned char *) md,track_size+media_size,0);
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: new ISO-9660 size : %.f (%fs)\n",
track_size+media_size, (track_size+media_size)/2048));
/* Copy type 255 CD001 descriptors from track to media descriptor buffer
and adjust their size entries */
for(i=1; i<16; i++) {
td= track_descr+i*2048;
md= skin->overwriteable_iso_head+(16+i)*2048;
if(td[0] != -1)
break;
/* demand media descrN[0] == track descrN[0] */
if(td[0] != md[0]) {
fprintf(stderr,
"cdrskin: SORRY : type mismatch of ISO volume descriptor #%d (%u <-> %u)\n",
i, ((unsigned int) td[0]) & 0xff, ((unsigned int) md[0])&0xff);
went_well= 0;
}
memcpy(md,td,2048);
Set_descr_iso_size((unsigned char *) md,track_size+media_size,0);
}
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: copied %d secondary ISO descriptors\n",
i-1));
/* write block 16 to 31 to media */
if(skin->verbosity>=Cdrskin_verbose_debuG)
ClN(fprintf(stderr,"cdrskin_debug: writing to media: blocks 16 to 31\n"));
ret= burn_random_access_write(skin->grabbed_drive, (off_t) (16*2048),
skin->overwriteable_iso_head+16*2048,
(off_t) (16*2048), 1);
if(ret<=0)
return(ret);
return(went_well);
}
#endif /* Cdrskin_libburn_has_random_access_rW */
/** Burn data via libburn according to the parameters set in skin. /** Burn data via libburn according to the parameters set in skin.
@ -5255,7 +5509,7 @@ int Cdrskin_burn(struct CdrskiN *skin, int flag)
struct burn_drive *drive; struct burn_drive *drive;
int ret,loop_counter= 0,max_track= -1,i,hflag,nwa,num, wrote_well= 2; int ret,loop_counter= 0,max_track= -1,i,hflag,nwa,num, wrote_well= 2;
int fifo_disabled= 0,fifo_percent,total_min_fill,min_buffer_fill= 101; int fifo_disabled= 0,fifo_percent,total_min_fill,min_buffer_fill= 101;
int use_data_image_size, needs_early_fifo_fill= 0; int use_data_image_size, needs_early_fifo_fill= 0,iso_size= -1;
double put_counter,get_counter,empty_counter,full_counter; double put_counter,get_counter,empty_counter,full_counter;
double start_time,last_time; double start_time,last_time;
double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0; double total_count= 0.0,last_count= 0.0,size,padding,sector_size= 2048.0;
@ -5403,11 +5657,47 @@ burn_failed:;
o= burn_write_opts_new(drive); o= burn_write_opts_new(drive);
burn_write_opts_set_perform_opc(o, 0); burn_write_opts_set_perform_opc(o, 0);
#ifdef Cdrskin_libburn_has_multI
burn_write_opts_set_multi(o,skin->multi);
#endif
#ifdef Cdrskin_libburn_has_set_start_bytE #ifdef Cdrskin_libburn_has_set_start_bytE
/* growisofs stunt: assessment of media and start for next session */
if((skin->grow_overwriteable_iso==1 || skin->grow_overwriteable_iso==2) &&
skin->media_is_overwriteable) {
/* Obtain ISO size from media, keep 64 kB head in memory */
ret= Cdrskin_overwriteable_iso_size(skin,&iso_size,0);
if(ret<0)
goto ex;
if(ret>0 && skin->write_start_address<0) {
skin->write_start_address= ((double) iso_size)*2048.0;
if(skin->verbosity>=Cdrskin_verbose_cmD)
ClN(printf(
"cdrskin: write start address by --grow_overwriteable_iso : %ds\n",
iso_size));
} else if(ret==0)
skin->grow_overwriteable_iso= 3; /* do not patch ISO header later on */
}
burn_write_opts_set_start_byte(o, skin->write_start_address); burn_write_opts_set_start_byte(o, skin->write_start_address);
#endif /* Cdrskin_libburn_has_set_start_bytE */
#ifdef Cdrskin_libburn_has_multI
if(skin->media_is_overwriteable && skin->multi) {
if(skin->grow_overwriteable_iso<=0) {
fprintf(stderr, "cdrskin: FATAL : -multi cannot leave a recognizeable end mark on this media.\n");
fprintf(stderr, "cdrskin: HINT : For ISO-9660 images try --start_overwriteable_iso -multi\n");
fprintf(stderr, "cdrskin: HINT : or --grow_overwriteable_iso -multi\n");
{ret= 0; goto ex;}
}
skin->multi= 0;
}
if(skin->multi && !skin->media_does_multi) {
if(skin->prodvd_cli_compatible) {
skin->multi= 0;
if(skin->verbosity>=Cdrskin_verbose_progresS)
fprintf(stderr, "cdrskin: NOTE : Ignored option -multi.\n");
}
}
burn_write_opts_set_multi(o,skin->multi);
#endif #endif
#ifdef Cdrskin_libburn_has_set_filluP #ifdef Cdrskin_libburn_has_set_filluP
burn_write_opts_set_fillup(o, skin->fill_up_media); burn_write_opts_set_fillup(o, skin->fill_up_media);
@ -5578,14 +5868,23 @@ fifo_filling_failed:;
wrote_well = burn_drive_wrote_well(drive); wrote_well = burn_drive_wrote_well(drive);
#endif #endif
#ifdef Cdrskin_libburn_has_random_access_rW
if(skin->media_is_overwriteable && skin->grow_overwriteable_iso>0 &&
wrote_well) {
/* growisofs final stunt : update volume descriptors at start of media */
ret= Cdrskin_grow_overwriteable_iso(skin,0);
if(ret<=0)
wrote_well= 0;
}
#endif /* Cdrskin_libburn_has_random_access_rW */
if(max_track<0) { if(max_track<0) {
printf("Track 01: Total bytes read/written: %.f/%.f (%.f sectors).\n", printf("Track 01: Total bytes read/written: %.f/%.f (%.f sectors).\n",
total_count,total_count,total_count/sector_size); total_count,total_count,total_count/sector_size);
} else { } else {
Cdrtrack_get_size(skin->tracklist[max_track],&size,&padding,&sector_size, Cdrtrack_get_size(skin->tracklist[max_track],&size,&padding,&sector_size,
&use_data_image_size,1); &use_data_image_size,1);
printf( printf("Track %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n",
"Track %-2.2d: Total bytes read/written: %.f/%.f (%.f sectors).\n",
max_track+1,size,size+padding,(size+padding)/sector_size); max_track+1,size,size+padding,(size+padding)/sector_size);
} }
if(skin->verbosity>=Cdrskin_verbose_progresS) if(skin->verbosity>=Cdrskin_verbose_progresS)
@ -5705,8 +6004,16 @@ int Cdrskin_msinfo(struct CdrskiN *skin, int flag)
drive= skin->drives[skin->driveno].drive; drive= skin->drives[skin->driveno].drive;
s= burn_disc_get_status(drive); s= burn_disc_get_status(drive);
if(s!=BURN_DISC_APPENDABLE) { if(s!=BURN_DISC_APPENDABLE) {
if(skin->grow_overwriteable_iso==1 || skin->grow_overwriteable_iso==2) {
lba= 0;
ret= Cdrskin_overwriteable_iso_size(skin,&nwa,0);
if(ret>0)
goto put_out;
}
Cdrskin_report_disc_status(skin,s,0); Cdrskin_report_disc_status(skin,s,0);
fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n"); fprintf(stderr,"cdrskin: FATAL : -msinfo can only operate on appendable (i.e. -multi) discs\n");
if(skin->grow_overwriteable_iso>0)
fprintf(stderr,"cdrskin: or on overwriteables with existing ISO-9660 file system.\n");
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
disc= burn_drive_get_disc(drive); disc= burn_drive_get_disc(drive);
@ -5769,6 +6076,8 @@ obtain_nwa:;
else else
nwa= aux_lba+11400; nwa= aux_lba+11400;
} }
put_out:;
if(skin->msinfo_fd>=0) { if(skin->msinfo_fd>=0) {
sprintf(msg,"%d,%d\n",lba,nwa); sprintf(msg,"%d,%d\n",lba,nwa);
write(skin->msinfo_fd,msg,strlen(msg)); write(skin->msinfo_fd,msg,strlen(msg));
@ -6306,6 +6615,15 @@ fs_equals:;
gracetime_equals:; gracetime_equals:;
sscanf(value_pt,"%d",&(skin->gracetime)); sscanf(value_pt,"%d",&(skin->gracetime));
#ifdef Cdrskin_libburn_has_get_multi_capS
#ifdef Cdrskin_libburn_has_random_access_rW
} else if(strncmp(argv[i],"--grow_overwriteable_iso",24)==0) {
skin->grow_overwriteable_iso= 1;
skin->use_data_image_size= 1;
#endif /* Cdrskin_libburn_has_random_access_rW */
#endif /* Cdrskin_libburn_has_get_multi_capS */
#else /* ! Cdrskin_extra_leaN */ #else /* ! Cdrskin_extra_leaN */
} else if( } else if(
@ -6323,7 +6641,6 @@ gracetime_equals:;
#endif /* Cdrskin_extra_leaN */ #endif /* Cdrskin_extra_leaN */
} else if(strcmp(argv[i],"--help")==0) { } else if(strcmp(argv[i],"--help")==0) {
/* is handled in Cdrpreskin_setup() */; /* is handled in Cdrpreskin_setup() */;
@ -6892,14 +7209,14 @@ int Cdrskin_run(struct CdrskiN *skin, int *exit_value, int flag)
{*exit_value= 8; goto ex;} {*exit_value= 8; goto ex;}
} }
#ifdef Cdrskin_libburn_has_random_access_writE #ifdef Cdrskin_libburn_has_random_access_rW
if(skin->do_direct_write) { if(skin->do_direct_write) {
skin->do_burn= 0; skin->do_burn= 0;
ret= Cdrskin_direct_write(skin,0); ret= Cdrskin_direct_write(skin,0);
if(ret<=0) if(ret<=0)
{*exit_value= 13; goto ex;} {*exit_value= 13; goto ex;}
} }
#endif /* Cdrskin_libburn_has_random_access_writE */ #endif /* Cdrskin_libburn_has_random_access_rW */
if(skin->do_burn || skin->tell_media_space) { if(skin->do_burn || skin->tell_media_space) {
if(skin->n_drives<=0) if(skin->n_drives<=0)

View File

@ -1 +1 @@
#define Cdrskin_timestamP "2007.08.25.155931" #define Cdrskin_timestamP "2007.08.26.200829"