New -check_media option -patch_lba0=

This commit is contained in:
Thomas Schmitt 2008-08-22 23:27:21 +00:00
parent d54ae82442
commit 3bfa3b4c9b
6 changed files with 311 additions and 69 deletions

View File

@ -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 "Aug 18, 2008"
.TH XORRISO 1 "Aug 22, 2008"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -939,7 +939,7 @@ E.g.:
"report_lba" prints files which are associated to image data blocks.
It tells the logical block address, the block number, the byte size,
and the path of each file. In future there may be reported more than one
line per file if thie file is very large.
line per file if the file is very large.
.br
E.g.:
.br
@ -1699,9 +1699,9 @@ to their read speed, save them to a file, and keep track of successfuly saved
blocks for further tries on the same media.
.TP
\fB\-check_media\fR [option [option ...]] --
Try to read data blocks from the indev drive and finally report about the
encountered quality. Several options may be used to modify the default
behavior.
Try to read data blocks from the indev drive, eventually copy them to a
disk file, and finally report about the encountered quality. Several options
may be used to modify the default behavior.
.br
An option consists of a keyword, a "=" character, and a value.
.br
@ -1712,7 +1712,7 @@ time_limit=28800 item_limit=100000
.br
abort_file=/var/opt/xorriso/do_abort_check_media
.br
data_to='' sector_map='' map_with_volid=off report=blocks
data_to='' sector_map='' map_with_volid=off patch_lba0=off report=blocks
.br
Non-default settings:
.br
@ -1757,6 +1757,20 @@ and their start block addresses, followed by binary bitmap data.
"map_with_volid=on" examines tracks whether they are ISO images and eventually
prints their volume ids into the human readable TOC of sector_map=.
.br
"patch_lba0=on" transfers within the data_to= file a copy of the currently
loaded session head to the start of that file and patches it to be valid
at that position.
This makes the loaded session the default session of the image file
when it gets mounted or loaded as stdio: drive. But it usually makes
the original session 1 inaccessible.
.br
"patch_lba0=force" performs "patch_lba0=on" even if xorriso believes
that the copied data are not valid.
.br
"patch_lba0=" may also bear a number. If it is 32 or higher it is taken as
start address of the session to be copied. In this case it is not necessary to
have an -indev and a loaded image. ":force" may be appended after the number.
.br
"use=sector_map" does not read any media but loads the file given by option
sector_map= and processes this virtual outcome.
.br

View File

@ -3125,6 +3125,19 @@ int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag)
}
int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o,
off_t start_byte, off_t end_byte, int flag)
{
int end_sector, i;
end_sector= end_byte / o->sector_size;
for(i= start_byte / o->sector_size; i <= end_sector; i++)
if(!Sectorbitmap_is_set(o, i, 0))
return(0);
return(1);
}
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag)
{
@ -3140,7 +3153,8 @@ int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
int i, run_start, run_value, start_sec, limit_sec, start_aligned;
int end_complete;
if(from->sectors * from->sector_size > to->sectors * to->sector_size)
if(((off_t) from->sectors) * ((off_t) from->sector_size) >
((off_t) to->sectors) * ((off_t) to->sector_size))
return(-1);
if(from->sector_size == to->sector_size) {
for(i= 0; i < from->map_size; i++)
@ -3175,6 +3189,21 @@ int Sectorbitmap_copy(struct SectorbitmaP *from, struct SectorbitmaP *to,
}
int Sectorbitmap_clone(struct SectorbitmaP *from, struct SectorbitmaP **clone,
int flag)
{
int ret;
ret= Sectorbitmap_new(clone, from->sectors, from->sector_size, 0);
if(ret <= 0)
return(ret);
ret= Sectorbitmap_copy(from, *clone, 0);
if(ret <= 0)
Sectorbitmap_destroy(clone, 0);
return(ret);
}
/* -------------------------- End SectorbitmaP ---------------------------- */
/* ---------------------------- CheckmediajoB ----------------------------- */
@ -3198,6 +3227,8 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media");
m->data_to_path[0]= 0;
m->data_to_fd= -1;
m->patch_lba0= 0;
m->patch_lba0_msc1= -1;
m->sector_map_path[0]= 0;
m->sector_map= NULL;
m->map_with_volid= 0;
@ -3211,6 +3242,8 @@ int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
{
if((*o) == NULL)
return(0);
if((*o)->data_to_fd != -1)
close((*o)->data_to_fd);
Sectorbitmap_destroy(&((*o)->sector_map), 0);
free((char *) *o);
*o= NULL;
@ -8862,6 +8895,12 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
map_sector_size == sector_size)
m= *map;
else {
if(*map != NULL) {
if(((off_t) (*map)->sectors) * ((off_t) (*map)->sector_size) >
((off_t) list_sectors) * ((off_t) sector_size))
list_sectors= (((off_t) (*map)->sectors) *
((off_t) (*map)->sector_size)) / sector_size + 1;
}
ret= Sectorbitmap_new(&m, list_sectors, sector_size, 0);
if(ret <= 0)
return(-1);
@ -9037,6 +9076,25 @@ ex:;
}
int Xorriso_open_job_data_to(struct XorrisO *xorriso,
struct CheckmediajoB *job, int flag)
{
char sfe[5*SfileadrL];
if(job->data_to_path[0] == 0)
return(2);
job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT,
S_IRUSR | S_IWUSR);
if(job->data_to_fd == -1) {
sprintf(xorriso->info_text, "Cannot open path %s",
Text_shellsafe(job->data_to_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
return(0);
}
return(1);
}
/* ---------------------------- Options API ------------------------ */
@ -9542,7 +9600,7 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
{
int ret, i, count, lba, blocks, quality;
int end_idx, old_idx, os_errno;
char quality_name[80];
char quality_name[80], head_buffer[64*1024];
double num;
struct SpotlisT *spotlist= NULL;
struct CheckmediajoB *job= NULL;
@ -9583,6 +9641,23 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
job->max_lba= num;
else
job->min_lba= num;
} else if(strncmp(argv[i], "patch_lba0=", 11) == 0) {
job->patch_lba0_msc1= -1;
if(strcmp(argv[i] + 11, "on") == 0)
job->patch_lba0= 1;
else if(strcmp(argv[i] + 11, "off") == 0)
job->patch_lba0= 0;
else if(strcmp(argv[i] + 11, "force") == 0)
job->patch_lba0= 2;
else if(argv[i][11] >= '1' && argv[i][11] <= '9') {
num= -1;
sscanf(argv[i] + 11, "%lf", &num);
if(num > 0x7fffffff || num < 0)
goto unknown_value;
job->patch_lba0_msc1= num;
job->patch_lba0= (num >= 32) + (strstr(argv[i] + 11, ":force") != NULL);
} else
goto unknown_value;
} else if(strncmp(argv[i], "report=", 7) == 0) {
if(strcmp(argv[i] + 7, "blocks") == 0)
job->report_mode= 0;
@ -9644,9 +9719,16 @@ unknown_value:;
}
if((job->report_mode == 1 || job->report_mode == 2) && job->use_dev == 1) {
/* >>> this combination makes no sense */;
sprintf(xorriso->info_text,
"-check_media: cannot report=*files while use=outdef");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(job->patch_lba0 && job->data_to_path[0] == 0) {
sprintf(xorriso->info_text,
"-check_media: cannot apply patch_lba0= while data_to= has empty value");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
if(job->use_dev == 2) {
@ -9668,14 +9750,29 @@ unknown_value:;
if(ret <= 0)
goto ex;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
xorriso->in_sector_map= job->sector_map;
job->sector_map= NULL;
ret= Sectorbitmap_clone(job->sector_map, &(xorriso->in_sector_map), 0);
if(ret <= 0)
goto ex;
} else {
ret= Xorriso_check_media(xorriso, &spotlist, job, 0);
if(ret <= 0)
goto ex;
}
if(job->patch_lba0) {
ret= Xorriso_open_job_data_to(xorriso, job, 0);
if(ret <= 0)
goto ex;
if(ret == 1) {
ret= Xorriso_update_iso_lba0(xorriso, job->patch_lba0_msc1, 0,
head_buffer, job,
(8 * (job->patch_lba0 == 1)) |
4 | (job->patch_lba0_msc1 < 0));
if(ret <= 0)
goto ex;
}
}
if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */
sprintf(xorriso->result_line,
"MCL layout : lba , size , quality\n");

View File

@ -531,6 +531,12 @@ int Xorriso_lst_append_binary(struct Xorriso_lsT **entry,
int Xorriso_lst_destroy(struct Xorriso_lsT **lstring, int flag);
/* Opens the -check_media data copy in for reading and writing
*/
int Xorriso_open_job_data_to(struct XorrisO *xorriso,
struct CheckmediajoB *job, int flag);
int Sfile_str(char target[SfileadrL], char *source, int flag);
@ -716,6 +722,8 @@ int Sectorbitmap_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_set_range(struct SectorbitmaP *o,
int start_sector, int sectors, int flag);
int Sectorbitmap_is_set(struct SectorbitmaP *o, int sector, int flag);
int Sectorbitmap_bytes_are_set(struct SectorbitmaP *o,
off_t start_byte, off_t end_byte, int flag);
int Sectorbitmap_get_layout(struct SectorbitmaP *o,
int *sectors, int *sector_size, int flag);

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.08.21.070602"
#define Xorriso_timestamP "2008.08.22.231051"

View File

@ -2976,11 +2976,6 @@ int Xorriso_restore_tree(struct XorrisO *xorriso, IsoDir *dir,
struct PermiteM *perm_stack_mem;
struct stat stbuf;
#ifdef NIX
struct stat target_stbuf;
target_is_dir;
#endif
perm_stack_mem= xorriso->perm_stack;
/* Avoiding large local memory objects in order to save stack space */
@ -3221,11 +3216,6 @@ int Xorriso_restore(struct XorrisO *xorriso,
struct stat stbuf;
struct PermiteM *perm_stack_mem;
#ifdef NIX
struct stat target_stbuf;
int target_is_dir;
#endif
perm_stack_mem= xorriso->perm_stack;
ret= Xorriso_path_is_excluded(xorriso, disk_path, !(flag&4));
@ -6182,6 +6172,148 @@ int Xorriso_atip(struct XorrisO *xorriso, int flag)
}
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
struct SpotlisT *spotlist, int read_chunk,
struct CheckmediajoB *job, int flag)
{
int sectors, sector_size, sector_blocks, ret;
struct SectorbitmaP *map;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
if(job->use_dev == 1)
return(1);
map= job->sector_map;
sectors= Spotlist_block_count(spotlist, 0);
if(sectors <= 0)
return(0);
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
sector_blocks= sector_size / 2048;
if(sector_blocks > 1)
sectors= sectors / sector_blocks + !!(sectors % sector_blocks);
ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0);
if(ret <= 0)
return(ret);
if(map != NULL)
Sectorbitmap_copy(map, xorriso->in_sector_map, 0);
ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk,
&(xorriso->in_sector_map), 1);
return(ret);
}
/*
@param flag bit0= obtain iso_lba from indev
bit1= head_buffer already contains a valid head
bit2= issue message about success
bit3= check whether source blocks are banned by in_sector_map
*/
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job,
int flag)
{
int ret, full_size, i;
char *headpt;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
off_t seek_ret;
if(flag & 1) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to learn current session lba", 1);
if(ret<=0)
return(0);
ret= isoburn_disc_get_msc1(drive, &iso_lba);
if(ret<=0)
return(0);
drive= NULL; /* indev will not be used furtherly */
}
if(job == NULL) {
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to update at lba 0 to 31", 2);
if(ret<=0)
return(0);
}
if(iso_lba < 32)
return(2);
if(!(flag & 2)) {
/* head_buffer was not filled yet. Read it from output media. */
if(job != NULL && job->data_to_fd >= 0) {
if((flag & 8) && job->sector_map != NULL) {
ret= Sectorbitmap_bytes_are_set(job->sector_map,
((off_t) iso_lba) * (off_t) 2048,
((off_t) (iso_lba + 32)) * ((off_t) 2048) - (off_t) 1, 0);
if(ret <= 0) {
sprintf(xorriso->info_text,
"ISO image head at lba %d is marked as invalid blocks in file copy",
iso_lba);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",
0);
return(0);
}
}
seek_ret= lseek(job->data_to_fd, ((off_t) 2048) * (off_t) iso_lba,
SEEK_SET);
if(seek_ret == -1)
ret= 0;
else
ret= read(job->data_to_fd, head_buffer, 64 * 1024);
if(ret < 64 * 1024) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"Cannot read ISO image head from file copy");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
return(0);
}
} else {
ret= isoburn_read_iso_head(drive, iso_lba, &isosize, head_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);
return(0);
}
}
}
/* patch ISO header */
full_size= iso_lba + isosize;
headpt= head_buffer + 32*1024;
for(i=0;i<4;i++)
headpt[87-i]= headpt[80+i]= (full_size >> (8*i)) & 0xff;
if(job != NULL) {
seek_ret= lseek(job->data_to_fd, (off_t) 0, SEEK_SET);
if(seek_ret == -1)
ret= 0;
else
ret= write(job->data_to_fd, head_buffer, 64 * 1024);
if(ret < 64 * 1024) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"Cannot write ISO image head to file copy");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
return(0);
}
} else {
ret= burn_random_access_write(drive, (off_t) 0, head_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);
return(0);
}
}
if(flag & 4) {
sprintf(xorriso->info_text,
"Overwrote LBA 0 to 31 by 64 KiB from LBA %d", iso_lba);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0);
}
return(1);
}
/* @param write_start_address is valid if >=0
@param tsize is valid if >0
@param flag bit0= grow_overwriteable_iso
@ -6191,7 +6323,8 @@ int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
char *track_source, off_t tsize, int flag)
{
int ret, fd, unpredicted_size, profile_number, is_cd= 0, dummy, nwa= -1;
int isosize= -1, i, full_size, do_isosize;
int isosize= -1, do_isosize;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
struct burn_write_opts *burn_options;
@ -6203,7 +6336,7 @@ int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
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 head_buffer[64*1024], *headpt;
char head_buffer[64*1024];
do_isosize= !!(flag&2);
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
@ -6378,6 +6511,17 @@ int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
ret= 0; goto ex;
}
#ifndef NIX
if(flag & 1) {
ret= Xorriso_update_iso_lba0(xorriso, nwa, isosize, head_buffer, NULL,
flag & 2);
if(ret <= 0)
goto ex;
}
#else
/* Update ISO header at lba 0 */
if((flag&1) && nwa >= 32) {
if(!do_isosize) {
@ -6407,6 +6551,8 @@ int Xorriso_burn_track(struct XorrisO *xorriso, off_t write_start_address,
}
}
#endif /* NIX */
sprintf(xorriso->info_text, "Writing to %s completed sucessfully.\n\n",
Text_shellsafe(xorriso->outdev,sfe,0));
Xorriso_info(xorriso, 0);
@ -6967,42 +7113,13 @@ ex:
}
int Xorriso_update_in_sector_map(struct XorrisO *xorriso,
struct SpotlisT *spotlist, int read_chunk,
struct CheckmediajoB *job, int flag)
{
int sectors, sector_size, sector_blocks, ret;
struct SectorbitmaP *map;
Sectorbitmap_destroy(&(xorriso->in_sector_map), 0);
if(job->use_dev == 1)
return(1);
map= job->sector_map;
sectors= Spotlist_block_count(spotlist, 0);
if(sectors <= 0)
return(0);
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
sector_blocks= sector_size / 2048;
if(sector_blocks > 1)
sectors= sectors / sector_blocks + !!(sectors % sector_blocks);
ret= Sectorbitmap_new(&(xorriso->in_sector_map), sectors, sector_size, 0);
if(ret <= 0)
return(ret);
if(map != NULL)
Sectorbitmap_copy(map, xorriso->in_sector_map, 0);
ret= Xorriso_spotlist_to_sectormap(xorriso, spotlist, read_chunk,
&(xorriso->in_sector_map), 1);
return(ret);
}
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
struct CheckmediajoB *job, int flag)
{
int media_blocks= 0, read_chunk= 16, ret, mode, start_lba= 0;
int blocks, os_errno, i, j, last_track_end= -1, track_blocks, track_lba;
int num_sessions, num_tracks, declare_untested= 0;
char sfe[5*SfileadrL], *toc_info= NULL;
char *toc_info= NULL;
struct burn_drive *drive;
struct burn_drive_info *dinfo;
struct isoburn_toc_disc *isoburn_disc= NULL;
@ -7043,17 +7160,9 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
}
Xorriso_toc_to_string(xorriso, &toc_info, 4 * !job->map_with_volid);
}
if(job->data_to_path[0]) {
job->data_to_fd= open(job->data_to_path, O_WRONLY | O_CREAT,
S_IRUSR | S_IWUSR);
if(job->data_to_fd == -1) {
sprintf(xorriso->info_text, "Cannot open path %s",
Text_shellsafe(job->data_to_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
{ret= 0; goto ex;}
}
}
ret= Xorriso_open_job_data_to(xorriso, job, 0);
if(ret <= 0)
goto ex;
Xorriso_pacifier_reset(xorriso, 0);
job->start_time= time(NULL);
mode= job->mode;
@ -7161,16 +7270,18 @@ no_content_visible:;
xorriso->pacifier_count, xorriso->pacifier_total, "", 1);
ret= 1;
ex:;
if(job->data_to_fd != -1)
close(job->data_to_fd);
job->data_to_fd= -1;
if(ret > 0)
ret= Xorriso_update_in_sector_map(xorriso, *spotlist, read_chunk, job, 0);
if(ret > 0 && job->sector_map_path[0]) {
if(ret > 0) {
ret= Xorriso_spotlist_to_sectormap(xorriso, *spotlist, read_chunk,
&(job->sector_map), 0);
if(ret > 0) {
if(ret > 0 && job->sector_map_path[0]) {
ret= Sectorbitmap_to_file(job->sector_map, job->sector_map_path, toc_info,
xorriso->info_text, &os_errno, 0);
if(ret <= 0) {

View File

@ -277,6 +277,16 @@ int Xorriso_libburn_adr(struct XorrisO *xorriso, char *address_string,
*/
int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag);
/*
@param flag bit0= obtain iso_lba from indev
bit1= head_buffer already contains a valid head
bit2= issue message about success
bit3= check whether source blocks are banned by in_sector_map
*/
int Xorriso_update_iso_lba0(struct XorrisO *xorriso, int iso_lba, int isosize,
char *head_buffer, struct CheckmediajoB *job,
int flag);
struct CheckmediajoB {
int use_dev; /* 0= use indev , 1= use outdev , 2= use sector map*/
@ -300,6 +310,8 @@ struct CheckmediajoB {
char data_to_path[SfileadrL];
int data_to_fd;
int patch_lba0;
int patch_lba0_msc1;
char sector_map_path[SfileadrL];
struct SectorbitmaP *sector_map;