Letting -check_media look for session checksum tags

This commit is contained in:
Thomas Schmitt 2009-08-14 21:15:52 +00:00
parent 11fe78ffb1
commit 7e40478a75
4 changed files with 166 additions and 56 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 12, 2009"
.TH XORRISO 1 "Aug 14, 2009"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -758,8 +758,8 @@ each single data file. If enabled then MD5 checksums get loaded from the image
if there are any. At image generation time they are computed for each file
which gets its data written into the new session. The checksums of files which
have their data in older sessions get copied into the new session.
Checksums can be exploited via options -check_md5, -check_md5_r, and via find
actions get_md5, check_md5.
Checksums can be exploited via options -check_md5, -check_md5_r, via find
actions get_md5, check_md5, and via -check_media.
.TP
\fB\-rom_toc_scan\fR "on"|"off"[:"emul_on"|"emul_off"]
Read-only drives do not tell the actual media type but show any media as
@ -2548,9 +2548,16 @@ description of options.
.br
The result list tells intervals of 2 KiB blocks with start address, number
of blocks and quality. Qualities which begin with "+" are
supposed to be valid readable data. Qualities with "-" are no valid data.
supposed to be valid readable data. Qualities with "-" are unreadable or
corrupted data.
"0" indicates qualities which are covered by the check run or are regularly
allowed to to be unreadable (e.g. gaps between tracks).
.br
Alternatively it is possible to report damaged files rather than blocks.
.br
If -md5 is on then the default mode what=tracks looks out for libisofs
checksum tags for the ISO session data and and eventually checks them
against the checksums computed from the data stream.
.TP
\fB\-check_media_defaults\fR [option [option ...]] --
Preset options for runs of -check_media, -extract_cut and best_effort

View File

@ -4199,9 +4199,9 @@ int Spotlist_get_item(struct SpotlisT *o, int idx,
if(idx < 0 || idx > o->list_count)
return(0);
if(idx == o->current_idx)
if(idx == o->current_idx && o->current_item != NULL)
li= o->current_item;
else if(idx == o->current_idx) {
else if(idx == o->current_idx + 1 && o->current_item != NULL) {
li= o->current_item->next;
} else {
li= o->list_start;
@ -4221,6 +4221,8 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
{
if(quality == Xorriso_read_quality_gooD)
strcpy(name, "+ good");
else if(quality == Xorriso_read_quality_md5_matcH)
strcpy(name, "+ md5_match");
else if(quality == Xorriso_read_quality_sloW)
strcpy(name, "+ slow");
else if(quality == Xorriso_read_quality_partiaL)
@ -4232,9 +4234,11 @@ char *Spotlist__quality_name(int quality, char name[80], int flag)
else if(quality == Xorriso_read_quality_invaliD)
strcpy(name, "- invalid");
else if(quality == Xorriso_read_quality_tao_enD)
strcpy(name, "- tao end");
strcpy(name, "0 tao end");
else if(quality == Xorriso_read_quality_off_tracK)
strcpy(name, "- off track");
strcpy(name, "0 off track");
else if(quality == Xorriso_read_quality_md5_mismatcH)
strcpy(name, "- md5_mismatch");
else if(quality == Xorriso_read_quality_unreadablE)
strcpy(name, "- unreadable");
else
@ -11589,7 +11593,7 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
struct SectorbitmaP *m;
int map_sectors= -1, map_sector_size= -1;
int list_sectors, list_blocks, sector_size, sector_blocks;
int replace_map= 0, count, i, lba, blocks, quality, ret;
int replace_map= 0, count, i, lba, blocks, quality, ret, pass;
sector_size= Spotlist_sector_size(spotlist, read_chunk, 0);
sector_blocks= sector_size / 2048;
@ -11629,15 +11633,22 @@ int Xorriso_spotlist_to_sectormap(struct XorrisO *xorriso,
}
count= Spotlist_count(spotlist, 0);
/* first set good bits, then eventueally override by bad bits */
for(pass= 0; pass < 2; pass++) {
for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0)
continue;
if(quality == Xorriso_read_quality_untesteD && !(flag & 1))
continue;
if(pass == 0 && quality < Xorriso_read_quality_untesteD)
continue;
else if(pass == 1 && quality >= Xorriso_read_quality_untesteD)
continue;
Sectorbitmap_set_range(m, lba / sector_blocks, blocks / sector_blocks,
quality >= Xorriso_read_quality_untesteD);
}
}
if(replace_map) {
Sectorbitmap_destroy(map, 0);
*map= m;
@ -13346,13 +13357,13 @@ int Xorriso_option_charset(struct XorrisO *xorriso, char *name, int flag)
/* Options -check_md5 and -check_md5_r
@param flag bit0= issue summary message
bit1= do not reset pacifier, no final pacifier message
bit2= do not issue pacifier messages at all
>>> bit2= do not issue pacifier messages at all
bit3= recursive: -check_md5_r
*/
int Xorriso_option_check_md5(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
{
int ret, i, mem_pci, end_idx, fret, sev;
int ret, i, mem_pci, end_idx, fret, sev, do_report= 0;
int optc= 0;
char **optv= NULL, *cpt, *severity;
struct FindjoB *job= NULL;
@ -13388,7 +13399,7 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
ret= -1; goto ex;
}
if(!(flag&2)) {
if(!(flag & (2 | 4))) {
Xorriso_pacifier_reset(xorriso, 0);
mem_lut= xorriso->last_update_time;
}
@ -13399,6 +13410,7 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
if(optc == 0) {
ret= Xorriso_check_session_md5(xorriso, severity, 0);
do_report= 1;
goto ex;
}
@ -13439,14 +13451,35 @@ int Xorriso_option_check_md5(struct XorrisO *xorriso,
}
ret= 1;
report_outcome:;
do_report= 1;
ex:;
if(!(flag & (2 | 4))) {
xorriso->pacifier_interval= mem_pci;
if(mem_lut!=xorriso->last_update_time && !(flag&2))
Xorriso_pacifier_callback(xorriso, "content bytes read",
xorriso->pacifier_count, 0, "", 1);
report_outcome:;
}
if(do_report) {
if(optc == 0) {
if(ret <= 0) {
sprintf(xorriso->result_line,
"MD5 MISMATCH WITH DATA OF LOADED SESSION !\n");
Xorriso_result(xorriso,0);
if(strcmp(severity, "ALL") != 0) {
sprintf(xorriso->info_text,
"Event triggered by MD5 comparison mismatch");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0);
}
} else {
sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n");
Xorriso_result(xorriso,0);
}
} else {
Xorriso_report_md5_outcome(xorriso, severity, 0);
ex:;
}
}
(*idx)= end_idx;
Xorriso_opt_args(xorriso, "-getfacl", argc, argv, *idx, &end_idx,
&optc, &optv, 256);
@ -13461,7 +13494,7 @@ ex:;
int Xorriso_option_check_media(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag)
{
int ret, i, count, lba, blocks, quality;
int ret, i, count, lba, blocks, quality, pass, was_md5= 0;
int end_idx, old_idx, os_errno;
char quality_name[80], head_buffer[64*1024];
struct SpotlisT *spotlist= NULL;
@ -13536,19 +13569,37 @@ int Xorriso_option_check_media(struct XorrisO *xorriso,
}
if(job->report_mode == 0 || job->report_mode == 2) { /* report blocks */
for(pass= 0; pass < 2; pass++) {
if(pass == 0) {
sprintf(xorriso->result_line,
"MCL layout : lba , size , quality\n");
"Media checks : lba , size , quality\n");
} else {
if(!was_md5)
break;
sprintf(xorriso->result_line,
"MD5 checks : lba , size , result\n");
}
Xorriso_result(xorriso,0);
count= Spotlist_count(spotlist, 0);
for(i= 0; i < count; i++) {
ret= Spotlist_get_item(spotlist, i, &lba, &blocks, &quality, 0);
if(ret <= 0)
continue;
sprintf(xorriso->result_line, "MCL item : %10d , %10d , %s\n",
if(pass == 0 && (quality == Xorriso_read_quality_md5_matcH ||
quality == Xorriso_read_quality_md5_mismatcH)) {
was_md5= 1;
continue;
}
else if(pass == 1 && !(quality == Xorriso_read_quality_md5_matcH ||
quality == Xorriso_read_quality_md5_mismatcH))
continue;
sprintf(xorriso->result_line, "%s: %10d , %10d , %s\n",
pass == 0 ? "Media region " : "MD5 tag range",
lba, blocks, Spotlist__quality_name(quality, quality_name, 0));
Xorriso_result(xorriso,0);
}
}
}
if(job->report_mode == 1 || job->report_mode == 2) { /* report files */
ret= Findjob_new(&findjob, "/", 0);
if(ret<=0) {

View File

@ -1 +1 @@
#define Xorriso_timestamP "2009.08.14.102355"
#define Xorriso_timestamP "2009.08.14.211648"

View File

@ -9195,14 +9195,15 @@ int Xorriso_msinfo(struct XorrisO *xorriso, int *msc1, int *msc2, int flag)
/* @param flag bit0= this is a follow-up session (i.e. on CD: TAO)
bit1= no pacifier messages
bit2= compute stream MD5 and look out for checksum tag
@return <=0 error, 1= done, 2= aborted due to limit
*/
int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct CheckmediajoB *job,
int from_lba, int block_count, int read_chunk,
int flag)
int md5_start, int flag)
{
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
int i, j, k, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0;
int start_sec, end_sec, first_value, fret;
char profile_name[80];
@ -9214,6 +9215,9 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0;
struct stat stbuf;
void *ctx= NULL;
char md5[16], tag_md5[16];
uint32_t pos, range_start, range_size;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to check media readability",
@ -9235,6 +9239,14 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
else if(job->retry == 0 && is_cd)
retry= 1;
if(flag & 4) {
ret= iso_md5_start(&ctx);
if(ret < 0) {
Xorriso_no_malloc_memory(xorriso, NULL, 0);
ret= -1; goto ex;
}
}
start_lba= from_lba;
to_read= read_chunk;
post_read_time= Sfile_microtime(0);
@ -9364,6 +9376,54 @@ abort_check:;
quality= Xorriso_read_quality_sloW;
}
if(ctx != NULL) {
for(j= 0; j < to_read; j++) {
ret= iso_util_decode_md5_tag(data + j * 2048, &pos, &range_start,
&range_size, tag_md5, 0);
if(ret == 1 && pos == i + j + from_lba) {
if(range_start != md5_start) {
sprintf(xorriso->info_text,
"Found MD5 checksum tag which covers different data range");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
sprintf(xorriso->info_text,
" Expected: %u Found: %u",
(unsigned int) md5_start, range_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE",0);
} else {
iso_md5_end(&ctx, md5);
for(k= 0; k < 16; k++)
if(tag_md5[k] != md5[k])
break;
if(k < 16 ) {
ret= Spotlist_add_item(spotlist, md5_start,
i + j + from_lba - md5_start,
Xorriso_read_quality_md5_mismatcH, 0);
sprintf(xorriso->info_text,
"Found NON-MATCHING MD5 checksum tag: start=%d size=%d",
md5_start, i + j + from_lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0,
"WARNING", 0);
} else {
ret= Spotlist_add_item(spotlist, md5_start,
i + j + from_lba - md5_start,
Xorriso_read_quality_md5_matcH, 0);
sprintf(xorriso->info_text,
"Found matching MD5 checksum tag: start=%d size=%d",
md5_start, i + j + from_lba - md5_start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "UPDATE",
0);
}
}
} else {
/* >>> ??? warn if ret == ISO_MD5_AREA_CORRUPTED */;
if(from_lba + i + j >= md5_start)
iso_md5_compute(ctx, data + j * 2048, 2048);
}
}
}
write_amount= data_count;
if(data_count > 0) {
read_count+= data_count;
@ -9424,6 +9484,8 @@ failed_to_write:;
ret= 1;
ex:
if(ctx != NULL)
iso_md5_end(&ctx, md5);
return(ret);
}
@ -9433,7 +9495,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
{
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;
int num_sessions, num_tracks, declare_untested= 0, md5_start;
char *toc_info= NULL;
struct burn_drive *drive;
struct burn_drive_info *dinfo;
@ -9492,7 +9554,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
blocks= job->max_lba + 1 - start_lba;
xorriso->pacifier_total= blocks;
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
read_chunk, 0);
read_chunk, 0, 0);
if(ret <= 0)
goto ex;
@ -9511,6 +9573,7 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
continue;
track_lba= isoburn_entry.start_lba;
track_blocks= isoburn_entry.track_blocks;
md5_start= track_lba;
if(i == 0 && j == 0) {
if(track_lba == 32) {
ret= burn_disc_get_multi_caps(drive, BURN_WRITE_NONE, &caps, 0);
@ -9547,7 +9610,8 @@ int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
goto ex;
} else {
ret= Xorriso_check_interval(xorriso, *spotlist, job, track_lba,
track_blocks, read_chunk, i > 0);
track_blocks, read_chunk, md5_start,
(i > 0) | (4 * (xorriso->do_md5 & 1)));
if(ret <= 0)
goto ex;
if(ret == 2)
@ -9572,7 +9636,7 @@ no_content_visible:;
goto no_content_visible;
xorriso->pacifier_total= blocks;
ret= Xorriso_check_interval(xorriso, *spotlist, job, start_lba, blocks,
read_chunk, 0);
read_chunk, 0, 0);
if(ret <= 0)
goto ex;
} else if(mode == 2) {
@ -9701,7 +9765,7 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
file_processed_bytes+= ((off_t) count) * (off_t) 2048;
ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
(flag & 2));
0, (flag & 2));
if(ret <= 0)
goto ex;
if (ret == 2) {
@ -12310,18 +12374,6 @@ int Xorriso_check_session_md5(struct XorrisO *xorriso, char *severity,
Xorriso_result(xorriso,0);
ret= Xorriso_check_md5_range(xorriso, (off_t) start_lba, (off_t) end_lba,
md5, 0);
if(ret <= 0) {
sprintf(xorriso->result_line,
"MD5 MISMATCH WITH DATA OF LOADED SESSION !\n");
Xorriso_result(xorriso,0);
if(strcmp(severity, "ALL") != 0) {
sprintf(xorriso->info_text, "Event triggered by MD5 comparison mismatch");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, severity, 0);
}
} else {
sprintf(xorriso->result_line, "Ok, session data match recorded md5.\n");
Xorriso_result(xorriso,0);
}
return(ret);
}