New option -extract_cut

This commit is contained in:
Thomas Schmitt 2008-09-02 16:48:59 +00:00
parent 33427c7bdb
commit 34a76c8eea
5 changed files with 270 additions and 14 deletions

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 XORRISO 1 "Aug 27, 2008" .TH XORRISO 1 "Sep 02, 2008"
.\" 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:
@ -1875,6 +1875,20 @@ restored.
Performs -extract with each of the iso_rr_path arguments. disk_path will be Performs -extract with each of the iso_rr_path arguments. disk_path will be
composed from iso_rr_path by replacing iso_rr_prefix by disk_prefix. composed from iso_rr_path by replacing iso_rr_prefix by disk_prefix.
.TP .TP
\fB\-extract_cut\fR iso_rr_path byte_offset byte_count disk_path
Copy a byte interval from a data file out of an ISO image into a newly created
disk file.
Two restrictions apply:
.br
The data bytes of iso_rr_path need to be already stored in the loaded ISO image
and byte_offset must be a multiple of 2048, e.g. an integer with suffix
s, m, or g.
.br
This option is implemented by a special run of -check_media.
Its main purpose is to allow handling of large files if they are not supported
by mount -t iso9660 and if the reading system is unable to buffer them as
a whole.
.TP
\fB\-cpx\fR iso_rr_path [***] disk_path \fB\-cpx\fR iso_rr_path [***] disk_path
Extract single leaf file objects from the ISO image and store them under Extract single leaf file objects from the ISO image and store them under
the address given by disk_path. If more then one iso_rr_path is given then the address given by disk_path. If more then one iso_rr_path is given then

View File

@ -3227,6 +3227,8 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media"); strcpy(m->abort_file_path, "/var/opt/xorriso/do_abort_check_media");
m->data_to_path[0]= 0; m->data_to_path[0]= 0;
m->data_to_fd= -1; m->data_to_fd= -1;
m->data_to_offset= 0;
m->data_to_limit= -1;
m->patch_lba0= 0; m->patch_lba0= 0;
m->patch_lba0_msc1= -1; m->patch_lba0_msc1= -1;
m->sector_map_path[0]= 0; m->sector_map_path[0]= 0;
@ -10731,6 +10733,44 @@ int Xorriso_option_extract(struct XorrisO *xorriso, char *iso_path,
} }
/* Option -extract_cut */
int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *isorr_path,
char *start, char *count, char *disk_path, int flag)
{
int ret;
double num;
off_t startbyte, bytecount;
num= Scanf_io_size(start, 0);
if(num<0 || num > 1.0e18) { /* 10^18 = 10^3 ^ 6 < 2^10 ^ 6 = 2^60 */
sprintf(xorriso->info_text,
"-extract_cut: startbyte address negative or much too large (%s)",
start);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
startbyte= num;
num= Scanf_io_size(count, 0);
if(num<=0 || num > 1.0e18) {
sprintf(xorriso->info_text,
"-extract_cut: bytecount zero, negative or much too large (%s)",
count);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
bytecount= num;
sprintf(xorriso->info_text,
"-extract_cut from %s , byte %.f to %.f, and store as %s",
disk_path, (double) startbyte, (double) (startbyte+bytecount),
isorr_path);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
ret= Xorriso_extract_cut(xorriso, isorr_path, disk_path,
startbyte, bytecount, 0);
return(ret);
}
/* Option -file_size_limit */ /* Option -file_size_limit */
int Xorriso_option_file_size_limit(struct XorrisO *xorriso, int Xorriso_option_file_size_limit(struct XorrisO *xorriso,
int argc, char **argv, int *idx, int flag) int argc, char **argv, int *idx, int flag)
@ -11399,6 +11439,8 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" Perform -extract_r with each iso_rr_path.", " Perform -extract_r with each iso_rr_path.",
" -extract_single iso_rr_path disk_path", " -extract_single iso_rr_path disk_path",
" Like -extract but with directory do not restore sub tree.", " Like -extract but with directory do not restore sub tree.",
" -extract_cut iso_rr_path byte_offset byte_count disk_path",
" Copy a byte interval from iso_rr_path to disk_path.",
" -cpx iso_rr_path [***] disk_path", " -cpx iso_rr_path [***] disk_path",
" Copy leaf file objects from ISO image to disk filesystem.", " Copy leaf file objects from ISO image to disk filesystem.",
" -cpax iso_rr_path [***] disk_path", " -cpax iso_rr_path [***] disk_path",
@ -13469,7 +13511,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"" ""
}; };
static char arg4_commands[][40]= { static char arg4_commands[][40]= {
"cut_out", "paste_in", "cut_out","extract_cut","paste_in",
"" ""
}; };
static char argn_commands[][40]= { static char argn_commands[][40]= {
@ -13761,6 +13803,17 @@ next_command:;
(*idx)+= 2; (*idx)+= 2;
ret= Xorriso_option_extract(xorriso, arg1, arg2, 0); ret= Xorriso_option_extract(xorriso, arg1, arg2, 0);
} else if(strcmp(cmd,"extract_cut")==0) {
(*idx)+= 4;
if((*idx)>argc) {
sprintf(xorriso->info_text,
"-extract_cut: Not enough arguments. Needed are: disk_path start count so_rr_path");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0;
} else
ret= Xorriso_option_extract_cut(xorriso, arg1, arg2,
argv[(*idx)-2], argv[(*idx)-1], 0);
} else if(strcmp(cmd,"extract_l")==0) { } else if(strcmp(cmd,"extract_l")==0) {
ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8); ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8);

View File

@ -1 +1 @@
#define Xorriso_timestamP "2008.08.27.122127" #define Xorriso_timestamP "2008.09.02.164803"

View File

@ -2398,8 +2398,10 @@ int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node,
#ifdef Xorriso_libisofs_0_6_7 #ifdef Xorriso_libisofs_0_6_7
ret= Xorriso__file_start_lba(node, &dummy, 0); ret= Xorriso__file_start_lba(node, &dummy, 0);
if(ret != 0) if(ret != 0) {
Xorriso_process_msg_queues(xorriso, 0);
return(0); return(0);
}
#else /* Xorriso_libisofs_0_6_7 */ #else /* Xorriso_libisofs_0_6_7 */
@ -2661,8 +2663,12 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
if(wanted>todo) if(wanted>todo)
wanted= todo; wanted= todo;
ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0); ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
if(ret<=0) if(ret<=0) {
/* >>> eventually call Xorriso_read_file_data() */;
break; break;
}
wret= write(write_fd, buf, ret); wret= write(write_fd, buf, ret);
if(wret>=0) { if(wret>=0) {
todo-= wret; todo-= wret;
@ -3650,8 +3656,17 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag)
} }
if(flag&(1|4)) if(flag&(1|4))
ret= 0; ret= 0;
else else {
ret= isoburn_read_iso_head(drive, lba, &image_blocks, volume_id, 1); ret= isoburn_read_iso_head(drive, lba, &image_blocks, volume_id, 1);
if(image_blocks > track_size) {
sprintf(xorriso->info_text,
"Session %d bears ISO image size %ds larger than track size %ds",
session_no + 1, image_blocks, track_size);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "WARNING",
0);
image_blocks= track_size;
}
}
if(ret>0 && track_no==0) { if(ret>0 && track_no==0) {
sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n", sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n",
session_no+1, lba, image_blocks , volume_id); session_no+1, lba, image_blocks , volume_id);
@ -5675,8 +5690,10 @@ int Xorriso_file_eval_damage(struct XorrisO *xorriso, IsoNode *node,
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
&size, 0); &size, 0);
if(ret <= 0) if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
return(ret); return(ret);
}
for(sect= 0; sect < lba_count; sect++) { for(sect= 0; sect < lba_count; sect++) {
for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) { for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) {
if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) { if(Sectorbitmap_is_set(map, i / sector_size, 0) == 0) {
@ -5711,8 +5728,10 @@ int Xorriso_report_lba(struct XorrisO *xorriso, char *show_path,
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
&size, 0); &size, 0);
if(ret < 0) if(ret < 0) {
Xorriso_process_msg_queues(xorriso, 0);
{ret= -1; goto ex;} {ret= -1; goto ex;}
}
if(ret == 0) if(ret == 0)
{ret= 1; goto ex;} /* it is ok to ignore other types */ {ret= 1; goto ex;} /* it is ok to ignore other types */
for(i= 0; i < lba_count; i++) { for(i= 0; i < lba_count; i++) {
@ -5964,8 +5983,10 @@ int Xorriso_findi_test(struct XorrisO *xorriso, struct FindjoB *job,
if(start_lba >= 0 && end_lba >= 0) { if(start_lba >= 0 && end_lba >= 0) {
ret= Xorriso__start_end_lbas(node, &lba_count, ret= Xorriso__start_end_lbas(node, &lba_count,
&file_start_lbas, &file_end_lbas, &size, 0); &file_start_lbas, &file_end_lbas, &size, 0);
if(ret <= 0) if(ret <= 0) {
Xorriso_process_msg_queues(xorriso, 0);
goto ex; goto ex;
}
for(i= 0; i < lba_count; i++) { for(i= 0; i < lba_count; i++) {
if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba) if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba)
{ret= 0; goto ex;} {ret= 0; goto ex;}
@ -7132,7 +7153,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct burn_drive *drive; struct burn_drive *drive;
struct burn_drive_info *dinfo; struct burn_drive_info *dinfo;
char data[64*1024], sfe[5*SfileadrL]; char data[64*1024], sfe[5*SfileadrL];
off_t data_count, to_read; off_t data_count, to_read, read_count= 0, write_amount;
double pre_read_time, post_read_time, time_diff, total_time_diff= 0; double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0; double last_abort_file_time= 0;
struct stat stbuf; struct stat stbuf;
@ -7285,9 +7306,17 @@ abort_check:;
if(time_diff > 1.0 && i > 0) if(time_diff > 1.0 && i > 0)
quality= Xorriso_read_quality_sloW; quality= Xorriso_read_quality_sloW;
} }
write_amount= data_count;
if(data_count > 0) { if(data_count > 0) {
read_count+= data_count;
if(job->data_to_limit >= 0 && read_count > job->data_to_limit)
write_amount-= (read_count - job->data_to_limit);
}
if(write_amount > 0) {
if(job->data_to_fd >= 0) { if(job->data_to_fd >= 0) {
ret= lseek(job->data_to_fd, ((off_t) (i + from_lba)) * (off_t) 2048, ret= lseek(job->data_to_fd,
((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset,
SEEK_SET); SEEK_SET);
if(ret == -1) { if(ret == -1) {
failed_to_write:; failed_to_write:;
@ -7298,7 +7327,7 @@ failed_to_write:;
"FAILURE", 0); "FAILURE", 0);
{ret= 0; goto ex;} {ret= 0; goto ex;}
} }
ret= write(job->data_to_fd, data, data_count); ret= write(job->data_to_fd, data, write_amount);
if(ret == -1) if(ret == -1)
goto failed_to_write; goto failed_to_write;
} }
@ -7525,3 +7554,158 @@ ex:;
burn_disc_free_multi_caps(&caps); burn_disc_free_multi_caps(&caps);
return(ret); return(ret);
} }
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;
off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr;
off_t new_file_base_bytes, upto_file_bytes;
char sfe[5*SfileadrL];
struct SpotlisT *spotlist= NULL;
struct CheckmediajoB *job= NULL;
upto_file_bytes= img_offset + bytes;
/* >>> make Xorriso_check_interval() ready for copying in byte granularity */
if(img_offset % (off_t) 2048) {
sprintf(xorriso->info_text,
"Image address offset is not a multiple of 2048");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas, &size,
0);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text,
"File object %s is currently not a data file from the loaded image",
Text_shellsafe(img_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
if(img_offset + bytes < size && bytes > 0)
size= img_offset + bytes;
ret= Checkmediajob_new(&job, 0);
if(ret <= 0)
goto ex;
ret= Spotlist_new(&spotlist, 0);
if(ret <= 0)
{ret= -1; goto ex;}
/* do overall job programming:
>>> ??? time_limit, item_limit
>>> ??? abort_file_path
*/
if(Sfile_str(job->data_to_path, disk_path, 0) <= 0)
{ret= -1; goto ex;}
Xorriso_open_job_data_to(xorriso, job, 0);
if(ret <= 0)
goto ex;
for(i= 0; i < lba_count && file_base_bytes < upto_file_bytes; i++) {
lba= start_lbas[i];
count= end_lbas[i] + 1 - start_lbas[i];
new_file_base_bytes= file_base_bytes + ((off_t) count) * (off_t) 2048;
/* skip intervals before img_offset */
if(new_file_base_bytes <= img_offset) {
file_base_bytes= new_file_base_bytes;
continue;
}
/* Eventually adjust first interval start */
img_adr= ((off_t) lba) * (off_t) 2048;
if(file_base_bytes < img_offset) {
img_adr+= img_offset - file_base_bytes;
lba= img_adr / (off_t) 2048;
count= end_lbas[i] + 1 - lba;
file_base_bytes= img_offset;
}
/* 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 */
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);
if(ret <= 0)
goto ex;
if (ret == 2) {
sprintf(xorriso->info_text, "Attempt aborted to extract data from %s",
Text_shellsafe(img_path, sfe, 0));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
file_base_bytes= new_file_base_bytes;
}
/* >>> use spotlist to evaluate damage */;
ret= 1;
ex:;
if(start_lbas != NULL)
free((char *) start_lbas);
if(end_lbas != NULL)
free((char *) end_lbas);
Spotlist_destroy(&spotlist, 0);
Checkmediajob_destroy(&job, 0);
return(ret);
}
int Xorriso_extract_cut(struct XorrisO *xorriso,
char *img_path, char *disk_path,
off_t img_offset, off_t bytes, int flag)
{
int ret, stbuf_ret;
double mem_lut= 0.0;
char eff_img_path[SfileadrL], eff_disk_path[SfileadrL];
IsoImage *volume;
IsoNode *node;
ret= Xorriso_get_volume(xorriso, &volume, 0);
if(ret<=0)
return(ret);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdi,
img_path, eff_img_path, 0);
if(ret<=0)
return(ret);
ret= Xorriso_node_from_path(xorriso, volume, eff_img_path, &node, 0);
if(ret<=0)
return(ret);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx,
disk_path, eff_disk_path, 2 | 4);
if(ret<=0)
return(ret);
Xorriso_pacifier_reset(xorriso, 0);
mem_lut= xorriso->last_update_time;
ret= Xorriso_handle_collision(xorriso, node, img_path, eff_disk_path,
disk_path, &stbuf_ret, 0);
if(ret<=0 || ret==3)
return(0);
ret= Xorriso_read_file_data(xorriso, node, eff_img_path, eff_disk_path,
img_offset, (off_t) 0, bytes, 0);
if(ret<=0)
return(ret);
ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
if(ret<=0)
return(ret);
if(mem_lut != xorriso->last_update_time)
Xorriso_pacifier_callback(xorriso, "sectors examined",
xorriso->pacifier_count, 0, "", 1);
return(1);
}

View File

@ -310,6 +310,8 @@ struct CheckmediajoB {
char data_to_path[SfileadrL]; char data_to_path[SfileadrL];
int data_to_fd; int data_to_fd;
off_t data_to_offset; /* usually 0 with image copy, negative with file copy */
off_t data_to_limit; /* used with file copy */
int patch_lba0; int patch_lba0;
int patch_lba0_msc1; int patch_lba0_msc1;
@ -332,6 +334,9 @@ struct CheckmediajoB {
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist, int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
struct CheckmediajoB *job, int flag); struct CheckmediajoB *job, int flag);
int Xorriso_extract_cut(struct XorrisO *xorriso,
char *img_path, char *disk_path,
off_t img_offset, off_t bytes, int flag);
#endif /* Xorrisoburn_includeD */ #endif /* Xorrisoburn_includeD */