From 62dbe3cbd0ab40dde5dfb9f765d7a8d6bd900742 Mon Sep 17 00:00:00 2001 From: Thomas Schmitt Date: Wed, 3 Sep 2008 14:33:14 +0000 Subject: [PATCH] New -error_behavior "file_extraction" behavior "best_effort" --- xorriso/xorriso.1 | 9 ++-- xorriso/xorriso.c | 11 ++++- xorriso/xorriso_private.h | 2 +- xorriso/xorriso_timestamp.h | 2 +- xorriso/xorrisoburn.c | 86 +++++++++++++++++++++++++++++++------ 5 files changed, 89 insertions(+), 21 deletions(-) diff --git a/xorriso/xorriso.1 b/xorriso/xorriso.1 index 74e28693..7e575428 100644 --- a/xorriso/xorriso.1 +++ b/xorriso/xorriso.1 @@ -1466,10 +1466,13 @@ It issues an own FAILURE event. "fatal" acts like "failure" but issues the own event as FATAL. This is the default. .br -With occasion "file_extraction" there are two behaviors: +With occasion "file_extraction" there are three behaviors: .br -"keep" maintains incompletely extracted files on disk. "delete" removes -files which encountered errors during content extraction. +"keep" maintains incompletely extracted files on disk. This is the default. +.br +"delete" removes files which encountered errors during content extraction. +.br +"best_effort" starts a revovery attempt by means of -extract_cut. .TP .B Dialog mode control: .TP diff --git a/xorriso/xorriso.c b/xorriso/xorriso.c index 8a2b8519..8cbfc9fc 100644 --- a/xorriso/xorriso.c +++ b/xorriso/xorriso.c @@ -4671,7 +4671,9 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag) Xorriso_status_result(xorriso,filter,fp,flag&2); is_default= (xorriso->extract_error_mode == 1); treatment= "keep"; - if(xorriso->extract_error_mode == 2) + if(xorriso->extract_error_mode == 0) + treatment= "best_effort"; + else if(xorriso->extract_error_mode == 2) treatment= "delete"; sprintf(line,"-error_behavior file_extraction %s\n", treatment); if(!(is_default && no_defaults)) @@ -10671,7 +10673,9 @@ unknown_behavior:; return(0); } } else if(strcmp(occasion, "file_extraction")==0) { - if(strcmp(behavior, "keep")==0) + if(strcmp(behavior, "best_effort")==0) + xorriso->extract_error_mode= 0; + else if(strcmp(behavior, "keep")==0) xorriso->extract_error_mode= 1; else if(strcmp(behavior, "delete")==0) xorriso->extract_error_mode= 2; @@ -11484,6 +11488,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag) " exit_value may be 0 or 32 to 63.", " -report_about severity Set the threshhold for events to be reported.", " Use -abort_on severities or: HINT, NOTE, UPDATE, DEBUG, ALL", +" -error_behavior \"image_loading\"|\"file_extraction\" behavior", +" Behavior \"best_effort\" is most endurant but may produce", +" results which are correct only on the first glimpse.", " -dialog After all arguments are processed, enter dialog mode.", " In this mode you may enter searchtexts or any of the options", " described here. One per line.", diff --git a/xorriso/xorriso_private.h b/xorriso/xorriso_private.h index fd4e8f99..06976dad 100644 --- a/xorriso/xorriso_private.h +++ b/xorriso/xorriso_private.h @@ -262,7 +262,7 @@ struct XorrisO { /* the global context of xorriso */ FILE *errfile_fp; int img_read_error_mode; /* 0=best_effort , 1=failure , 2=fatal */ - int extract_error_mode; /* 0=(not yet: best_effort) , 1=keep , 2=delete */ + int extract_error_mode; /* 0=best_effort , 1=keep , 2=delete */ char return_with_text[20]; int return_with_severity; diff --git a/xorriso/xorriso_timestamp.h b/xorriso/xorriso_timestamp.h index d02b9dd4..8c2f539c 100644 --- a/xorriso/xorriso_timestamp.h +++ b/xorriso/xorriso_timestamp.h @@ -1 +1 @@ -#define Xorriso_timestamP "2008.09.02.164803" +#define Xorriso_timestamP "2008.09.03.143218" diff --git a/xorriso/xorrisoburn.c b/xorriso/xorrisoburn.c index 5cd31242..4061156d 100644 --- a/xorriso/xorrisoburn.c +++ b/xorriso/xorrisoburn.c @@ -76,6 +76,11 @@ int Xorriso_findi_iter(struct XorrisO *xorriso, IsoDir *dir_node, off_t *mem, int Xorriso__file_start_lba(IsoNode *node, int *lba, int flag); +int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, + char *img_path, char *disk_path, + off_t img_offset, off_t disk_offset, + off_t bytes, int flag); + #define LIBISO_ISDIR(node) (iso_node_get_type(node) == LIBISO_DIR) #define LIBISO_ISREG(node) (iso_node_get_type(node) == LIBISO_FILE) @@ -2585,7 +2590,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL]; char buf[32*1024], type_text[5], temp_path[SfileadrL]; char *link_target, *open_path_pt= NULL; - off_t todo, size, seek_ret, last_p_count= 0; + off_t todo= 0, size, seek_ret, last_p_count= 0, already_done; void *data_stream= NULL; mode_t mode; dev_t dev= 0; @@ -2664,9 +2669,29 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, wanted= todo; ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0); if(ret<=0) { - - /* >>> eventually call Xorriso_read_file_data() */; - + if(xorriso->extract_error_mode == 0) { + close(write_fd); + write_fd= -1; + already_done= (size - todo) / (off_t) 2048; + already_done*= (off_t) 2048; + sprintf(xorriso->info_text, + "Starting best_effort handling on ISO file %s at byte %.f", + Text_shellsafe(img_path, sfe, 0), (double) already_done); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "NOTE", 0); + ret= Xorriso_read_file_data(xorriso, node, img_path, open_path_pt, + already_done, already_done, size - already_done, 2); + if(ret >= 0) + xorriso->pacifier_byte_count+= todo; + if(ret > 0) + todo= 0; + else + todo= -1; + } + if(ret <= 0) { + sprintf(xorriso->info_text, "Cannot read all bytes from ISO file %s", + Text_shellsafe(img_path, sfe, 0)); + Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0); + } break; } wret= write(write_fd, buf, ret); @@ -2689,7 +2714,8 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node, break; } } - close(write_fd); + if(write_fd > 0) + close(write_fd); write_fd= -1; if(todo > 0 && xorriso->extract_error_mode == 2 && open_path_pt != NULL) { unlink(open_path_pt); @@ -2788,6 +2814,8 @@ restore_properties:; ret= 1; else ret= Xorriso_restore_properties(xorriso, disk_path, node, flag&1); + if(todo < 0) + ret= 0; ex:; if(write_fd >= 0) { close(write_fd); @@ -7138,6 +7166,7 @@ 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 @return <=0 error, 1= done, 2= aborted due to limit */ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist, @@ -7343,10 +7372,13 @@ failed_to_write:; start_lba= i + from_lba; prev_quality= quality; } - xorriso->pacifier_count+= to_read; - if(post_read_time - xorriso->last_update_time >= xorriso->pacifier_interval) - Xorriso_pacifier_callback(xorriso, "sectors examined", + if(!(flag & 2)) { + xorriso->pacifier_count+= to_read; + if(post_read_time - xorriso->last_update_time >= + xorriso->pacifier_interval) + Xorriso_pacifier_callback(xorriso, "sectors examined", xorriso->pacifier_count, xorriso->pacifier_total, "", 0); + } } if(prev_quality >= 0) { ret= Spotlist_add_item(spotlist, start_lba, @@ -7556,15 +7588,17 @@ ex:; } +/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages +*/ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, char *img_path, char *disk_path, off_t img_offset, off_t disk_offset, off_t bytes, int flag) { int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16; - int lba, count; + int lba, count, blocks, quality, spot, bad_extract= 0; off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr; - off_t new_file_base_bytes, upto_file_bytes; + off_t new_file_base_bytes, upto_file_bytes, start_byte= 0; char sfe[5*SfileadrL]; struct SpotlisT *spotlist= NULL; struct CheckmediajoB *job= NULL; @@ -7632,13 +7666,13 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, /* Eventually omit surplus blocks */ if(new_file_base_bytes > upto_file_bytes) count-= (new_file_base_bytes - upto_file_bytes) / (off_t) 2048; - /* adjust job */ + /* Adjust job */ job->data_to_offset= file_processed_bytes - img_adr + disk_offset; job->data_to_limit= size - file_base_bytes; file_processed_bytes+= ((off_t) count) * (off_t) 2048; ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk, - 0); + (flag & 2)); if(ret <= 0) goto ex; if (ret == 2) { @@ -7650,9 +7684,33 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node, file_base_bytes= new_file_base_bytes; } - /* >>> use spotlist to evaluate damage */; + /* Use spotlist to evaluate damage */ + file_base_bytes= 0; + count= Spotlist_count(spotlist, 0); + for(spot= 0; spot < count; spot++) { + ret= Spotlist_get_item(spotlist, spot, &lba, &blocks, &quality, 0); + if(ret <= 0) + continue; + if(quality < Xorriso_read_quality_valiD) { + for(i= 0; i < lba_count; i++) { + if(start_lbas[i] <= lba && end_lbas[i] >= lba) { + start_byte= (lba - start_lbas[i]) * (off_t) 2048 + file_base_bytes; + break; + } + file_base_bytes+= ((off_t) (end_lbas[i] + 1 - start_lbas[i])) + * (off_t) 2048; + } + if(i < lba_count) { + sprintf(xorriso->info_text, "Bad extract : %14.f , %14.f , %s\n", + (double) start_byte, ((double) blocks) * 2048.0, + Text_shellsafe(disk_path, sfe, 0)); + Xorriso_info(xorriso, 0); + bad_extract= 1; + } + } + } - ret= 1; + ret= !bad_extract; ex:; if(start_lbas != NULL) free((char *) start_lbas);