Enhanced option -extract_cut for handling filtered files
This commit is contained in:
parent
e784320c2f
commit
4fdf92da42
@ -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 "May 09, 2009"
|
||||
.TH XORRISO 1 "May 14, 2009"
|
||||
.\" Please adjust this date whenever revising the manpage.
|
||||
.\"
|
||||
.\" Some roff macros, for reference:
|
||||
@ -1138,7 +1138,7 @@ Examples:
|
||||
.br
|
||||
/usr/bin/bzip2 --
|
||||
.br
|
||||
-external_filter bunzip2 suffix=.bz2:remove_suffix:if_nonempty \\
|
||||
-external_filter bunzip2 suffix=.bz2:remove_suffix \\
|
||||
.br
|
||||
/usr/bin/bunzip2 --
|
||||
.TP
|
||||
@ -2131,7 +2131,8 @@ With occasion "file_extraction" there are three behaviors:
|
||||
.br
|
||||
"delete" removes files which encountered errors during content extraction.
|
||||
.br
|
||||
"best_effort" starts a revovery attempt by means of -extract_cut.
|
||||
"best_effort" starts a revovery attempt by means of -extract_cut if the
|
||||
file content stems from the loaded ISO image and is not filtered.
|
||||
.TP
|
||||
.B Dialog mode control:
|
||||
.TP
|
||||
@ -2633,17 +2634,15 @@ composed from iso_rr_path by replacing iso_rr_prefix by disk_prefix.
|
||||
\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:
|
||||
The main purpose for this 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.
|
||||
.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 and governed by
|
||||
most of the options which can be set by -check_media_defaults.
|
||||
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.
|
||||
If the data bytes of iso_rr_path are stored in the loaded ISO image,
|
||||
and no filter is applied,
|
||||
and byte_offset is a multiple of 2048, then a special run of -check_media
|
||||
is performed. It may be quicker and more rugged than the general reading
|
||||
method.
|
||||
.TP
|
||||
\fB\-cpx\fR iso_rr_path [***] disk_path
|
||||
Extract single leaf file objects from the ISO image and store them under
|
||||
|
@ -14693,8 +14693,8 @@ int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path,
|
||||
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),
|
||||
iso_rr_path);
|
||||
iso_rr_path, (double) startbyte, (double) (startbyte+bytecount),
|
||||
disk_path);
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
|
||||
|
||||
ret= Xorriso_extract_cut(xorriso, iso_rr_path, disk_path,
|
||||
|
@ -1 +1 @@
|
||||
#define Xorriso_timestamP "2009.05.09.201742"
|
||||
#define Xorriso_timestamP "2009.05.14.082045"
|
||||
|
@ -3159,8 +3159,25 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
|
||||
}
|
||||
|
||||
|
||||
int Xorriso_is_plain_image_file(struct XorrisO *xorriso, IsoNode *node,
|
||||
int flag)
|
||||
{
|
||||
int ret, lba;
|
||||
IsoStream *stream;
|
||||
|
||||
ret= Xorriso__file_start_lba(node, &lba, 0);
|
||||
if(ret > 0) { /* Stream source is from loaded image */
|
||||
stream= iso_file_get_stream((IsoFile *) node);
|
||||
if(stream != NULL)
|
||||
if(iso_stream_get_input_stream(stream, 0) == NULL)
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/* @param flag bit0= Minimal transfer: access permissions only
|
||||
bit1= offset and bytes is valid for writing to regular file
|
||||
bit1= *_offset and bytes are valid for writing to regular file
|
||||
bit2= This is not a parameter. Do not report if ignored
|
||||
bit3= do not restore properties
|
||||
bit4= issue pacifier messages with long lasting copying
|
||||
@ -3168,15 +3185,16 @@ int Xorriso_restore_implicit_properties(struct XorrisO *xorriso,
|
||||
2 regularly not installed (disallowed device, UNIX domain socket)
|
||||
*/
|
||||
int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
||||
char *img_path, char *disk_path,
|
||||
off_t offset, off_t bytes, int flag)
|
||||
char *img_path, off_t img_offset,
|
||||
char *disk_path, off_t disk_offset, off_t bytes,
|
||||
int flag)
|
||||
{
|
||||
int ret= 0, write_fd= -1, wanted, wret, open_flags, l_errno= 0;
|
||||
int target_deleted= 0;
|
||||
char *what= "[unknown filetype]", sfe[5*SfileadrL], sfe2[5*SfileadrL];
|
||||
char buf[32*1024], type_text[5], temp_path[SfileadrL];
|
||||
char buf[32*1024], type_text[5], temp_path[SfileadrL], *buf_pt;
|
||||
char *link_target, *open_path_pt= NULL;
|
||||
off_t todo= 0, size, seek_ret, last_p_count= 0, already_done;
|
||||
off_t todo= 0, size, seek_ret, last_p_count= 0, already_done, read_count= 0;
|
||||
void *data_stream= NULL;
|
||||
mode_t mode;
|
||||
dev_t dev= 0;
|
||||
@ -3228,7 +3246,7 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
||||
}
|
||||
if(write_fd==-1) {
|
||||
open_flags= O_WRONLY|O_CREAT;
|
||||
if(offset==0 || !(flag&2))
|
||||
if(disk_offset==0 || !(flag&2))
|
||||
open_flags|= O_EXCL;
|
||||
write_fd= open(open_path_pt, open_flags, S_IRUSR|S_IWUSR);
|
||||
l_errno= errno;
|
||||
@ -3239,12 +3257,12 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
||||
if(flag&2) {
|
||||
if(bytes<size)
|
||||
todo= size= bytes;
|
||||
seek_ret= lseek(write_fd, offset, SEEK_SET);
|
||||
seek_ret= lseek(write_fd, disk_offset, SEEK_SET);
|
||||
l_errno= errno;
|
||||
if(seek_ret == -1) {
|
||||
sprintf(xorriso->info_text,
|
||||
"Cannot address byte %.f in filesystem path %s",
|
||||
(double) offset, Text_shellsafe(open_path_pt, sfe, 0));
|
||||
(double) disk_offset, Text_shellsafe(open_path_pt, sfe, 0));
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE",0);
|
||||
goto cannot_restore;
|
||||
}
|
||||
@ -3255,7 +3273,8 @@ 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) {
|
||||
if(xorriso->extract_error_mode == 0) {
|
||||
if(xorriso->extract_error_mode == 0 &&
|
||||
Xorriso_is_plain_image_file(xorriso, node, 0)) {
|
||||
close(write_fd);
|
||||
write_fd= -1;
|
||||
already_done= (size - todo) / (off_t) 2048;
|
||||
@ -3280,7 +3299,18 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
|
||||
}
|
||||
break;
|
||||
}
|
||||
wret= write(write_fd, buf, ret);
|
||||
read_count+= ret;
|
||||
buf_pt= buf;
|
||||
|
||||
if(img_offset > read_count - ret) {
|
||||
/* skip the desired amount of bytes */
|
||||
if(read_count <= img_offset)
|
||||
continue;
|
||||
buf_pt= buf + (img_offset - (read_count - ret));
|
||||
ret= read_count - img_offset;
|
||||
}
|
||||
|
||||
wret= write(write_fd, buf_pt, ret);
|
||||
if(wret>=0) {
|
||||
todo-= wret;
|
||||
xorriso->pacifier_byte_count+= wret;
|
||||
@ -3509,8 +3539,8 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso,
|
||||
first_part_node= part_node;
|
||||
if(offset+bytes>total_bytes)
|
||||
bytes= total_bytes-offset;
|
||||
ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, disk_path,
|
||||
offset, bytes,
|
||||
ret= Xorriso_tree_restore_node(xorriso, part_node, part_path, (off_t) 0,
|
||||
disk_path, offset, bytes,
|
||||
(!!(flag&64)) | 2 | (flag&4) | 8 | ( 16 * !(flag&2)));
|
||||
if(ret<=0)
|
||||
goto restoring_failed;
|
||||
@ -3534,8 +3564,8 @@ int Xorriso_restore_disk_object(struct XorrisO *xorriso,
|
||||
|
||||
img_path_pt= img_path;
|
||||
|
||||
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, disk_path,
|
||||
offset, bytes,
|
||||
ret= Xorriso_tree_restore_node(xorriso, node, img_path_pt, (off_t) 0,
|
||||
disk_path, offset, bytes,
|
||||
(flag&(4|8)) | (!!(flag&64)) | ((flag&1)<<1) | ( 16 * !(flag&2)));
|
||||
if(ret>0 && (flag&8))
|
||||
ret= Xorriso_restore_properties(xorriso, disk_path, node, 2 | !!(flag&64));
|
||||
@ -7848,6 +7878,12 @@ int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
return(0);
|
||||
}
|
||||
if(!iso_stream_is_repeatable(iso_stream)) {
|
||||
sprintf(xorriso->info_text,
|
||||
"The data production of the file in the image is one-time only");
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
return(0);
|
||||
}
|
||||
ret= iso_stream_open(iso_stream);
|
||||
if(ret<0) {
|
||||
sprintf(xorriso->info_text,
|
||||
@ -7855,13 +7891,6 @@ int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
return(0);
|
||||
}
|
||||
if(!iso_stream_is_repeatable(iso_stream)) {
|
||||
sprintf(xorriso->info_text,
|
||||
"The data production of the file in the image is one-time only");
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
iso_stream_close(iso_stream);
|
||||
return(0);
|
||||
}
|
||||
Xorriso_process_msg_queues(xorriso,0);
|
||||
*stream= iso_stream;
|
||||
|
||||
@ -8669,9 +8698,9 @@ 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;
|
||||
int ret, stbuf_ret, read_raw;
|
||||
double mem_lut= 0.0;
|
||||
char eff_img_path[SfileadrL], eff_disk_path[SfileadrL];
|
||||
char eff_img_path[SfileadrL], eff_disk_path[SfileadrL], sfe[SfileadrL*5];
|
||||
IsoImage *volume;
|
||||
IsoNode *node;
|
||||
|
||||
@ -8696,10 +8725,36 @@ int Xorriso_extract_cut(struct XorrisO *xorriso,
|
||||
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);
|
||||
|
||||
/* If it is a non-filtered stream from the ISO image
|
||||
and img_offset is a multiple of 2048
|
||||
then use Xorriso_read_file_data() for random access offset.
|
||||
*/
|
||||
if(!LIBISO_ISREG(node)) {
|
||||
Xorriso_msgs_submit(xorriso, 0, eff_disk_path, 0, "ERRFILE", 0);
|
||||
sprintf(xorriso->info_text, "-extract_cut: ISO file %s is not a data file",
|
||||
Text_shellsafe(eff_img_path, sfe, 0));
|
||||
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
|
||||
return(0);
|
||||
}
|
||||
read_raw= 0;
|
||||
if((img_offset % 2048) == 0) {
|
||||
ret= Xorriso_is_plain_image_file(xorriso, node, 0);
|
||||
if(ret > 0)
|
||||
read_raw= 1;
|
||||
}
|
||||
if (read_raw) {
|
||||
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);
|
||||
} else {
|
||||
ret= Xorriso_tree_restore_node(xorriso, node, eff_img_path, img_offset,
|
||||
eff_disk_path, (off_t) 0, bytes, 2 | 8);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
}
|
||||
|
||||
ret= Xorriso_restore_properties(xorriso, eff_disk_path, node, 0);
|
||||
if(ret<=0)
|
||||
return(ret);
|
||||
|
Loading…
Reference in New Issue
Block a user