New -error_behavior "file_extraction" behavior "best_effort"

This commit is contained in:
2008-09-03 14:33:14 +00:00
parent 34a76c8eea
commit 81acf83a11
5 changed files with 89 additions and 21 deletions

View File

@ -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);