New option -extract_cut
This commit is contained in:
parent
33427c7bdb
commit
34a76c8eea
@ -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 27, 2008"
|
||||
.TH XORRISO 1 "Sep 02, 2008"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@ -1875,6 +1875,20 @@ restored.
|
||||
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.
|
||||
.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
|
||||
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
|
||||
|
@ -3227,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->data_to_offset= 0;
|
||||
m->data_to_limit= -1;
|
||||
m->patch_lba0= 0;
|
||||
m->patch_lba0_msc1= -1;
|
||||
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 */
|
||||
int Xorriso_option_file_size_limit(struct XorrisO *xorriso,
|
||||
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.",
|
||||
" -extract_single iso_rr_path disk_path",
|
||||
" 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",
|
||||
" Copy leaf file objects from ISO image to disk filesystem.",
|
||||
" -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]= {
|
||||
"cut_out", "paste_in",
|
||||
"cut_out","extract_cut","paste_in",
|
||||
""
|
||||
};
|
||||
static char argn_commands[][40]= {
|
||||
@ -13761,6 +13803,17 @@ next_command:;
|
||||
(*idx)+= 2;
|
||||
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) {
|
||||
ret= Xorriso_option_map_l(xorriso, argc, argv, idx, 3<<8);
|
||||
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2008.08.27.122127"
|
||||
#define Xorriso_timestamP "2008.09.02.164803"
|
||||
|
@ -2398,8 +2398,10 @@ int Xorriso_restore_is_identical(struct XorrisO *xorriso, void *in_node,
|
||||
#ifdef Xorriso_libisofs_0_6_7
|
||||
|
||||
ret= Xorriso__file_start_lba(node, &dummy, 0);
|
||||
if(ret != 0)
|
||||
if(ret != 0) {
|
||||
Xorriso_process_msg_queues(xorriso, 0);
|
||||
return(0);
|
||||
}
|
||||
|
||||
#else /* Xorriso_libisofs_0_6_7 */
|
||||
|
||||
@ -2661,8 +2663,12 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
||||
if(wanted>todo)
|
||||
wanted= todo;
|
||||
ret= Xorriso_iso_file_read(xorriso, data_stream, buf, wanted, 0);
|
||||
if(ret<=0)
|
||||
if(ret<=0) {
|
||||
|
||||
/* >>> eventually call Xorriso_read_file_data() */;
|
||||
|
||||
break;
|
||||
}
|
||||
wret= write(write_fd, buf, ret);
|
||||
if(wret>=0) {
|
||||
todo-= wret;
|
||||
@ -3650,8 +3656,17 @@ int Xorriso_toc(struct XorrisO *xorriso, int flag)
|
||||
}
|
||||
if(flag&(1|4))
|
||||
ret= 0;
|
||||
else
|
||||
else {
|
||||
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) {
|
||||
sprintf(respt, "ISO session : %3d , %9d , %9ds , %s\n",
|
||||
session_no+1, lba, image_blocks , volume_id);
|
||||
@ -4188,7 +4203,7 @@ int Xorriso__node_lba_cmp(const void *node1, const void *node2)
|
||||
int lba1= 0, lba2= 0;
|
||||
|
||||
ret= Xorriso__file_start_lba(*((IsoNode **) node1), &lba1, 0);
|
||||
if(ret!=1)
|
||||
if(ret!=1)
|
||||
lba1= 0;
|
||||
ret= Xorriso__file_start_lba(*((IsoNode **) node2), &lba2, 0);
|
||||
if(ret!=1)
|
||||
@ -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,
|
||||
&size, 0);
|
||||
if(ret <= 0)
|
||||
if(ret <= 0) {
|
||||
Xorriso_process_msg_queues(xorriso, 0);
|
||||
return(ret);
|
||||
}
|
||||
for(sect= 0; sect < lba_count; sect++) {
|
||||
for(i= start_lbas[sect]; i <= end_lbas[sect]; i+= sector_size) {
|
||||
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,
|
||||
&size, 0);
|
||||
if(ret < 0)
|
||||
if(ret < 0) {
|
||||
Xorriso_process_msg_queues(xorriso, 0);
|
||||
{ret= -1; goto ex;}
|
||||
}
|
||||
if(ret == 0)
|
||||
{ret= 1; goto ex;} /* it is ok to ignore other types */
|
||||
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) {
|
||||
ret= Xorriso__start_end_lbas(node, &lba_count,
|
||||
&file_start_lbas, &file_end_lbas, &size, 0);
|
||||
if(ret <= 0)
|
||||
if(ret <= 0) {
|
||||
Xorriso_process_msg_queues(xorriso, 0);
|
||||
goto ex;
|
||||
}
|
||||
for(i= 0; i < lba_count; i++) {
|
||||
if(file_end_lbas[i] < start_lba || file_start_lbas[i] > end_lba)
|
||||
{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_info *dinfo;
|
||||
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 last_abort_file_time= 0;
|
||||
struct stat stbuf;
|
||||
@ -7285,10 +7306,18 @@ abort_check:;
|
||||
if(time_diff > 1.0 && i > 0)
|
||||
quality= Xorriso_read_quality_sloW;
|
||||
}
|
||||
|
||||
write_amount= data_count;
|
||||
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) {
|
||||
ret= lseek(job->data_to_fd, ((off_t) (i + from_lba)) * (off_t) 2048,
|
||||
SEEK_SET);
|
||||
ret= lseek(job->data_to_fd,
|
||||
((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset,
|
||||
SEEK_SET);
|
||||
if(ret == -1) {
|
||||
failed_to_write:;
|
||||
sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of %s",
|
||||
@ -7298,7 +7327,7 @@ failed_to_write:;
|
||||
"FAILURE", 0);
|
||||
{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)
|
||||
goto failed_to_write;
|
||||
}
|
||||
@ -7525,3 +7554,158 @@ ex:;
|
||||
burn_disc_free_multi_caps(&caps);
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -310,6 +310,8 @@ struct CheckmediajoB {
|
||||
|
||||
char data_to_path[SfileadrL];
|
||||
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_msc1;
|
||||
|
||||
@ -332,6 +334,9 @@ struct CheckmediajoB {
|
||||
int Xorriso_check_media(struct XorrisO *xorriso, struct SpotlisT **spotlist,
|
||||
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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user