Commit 2faac546 authored by Thomas Schmitt's avatar Thomas Schmitt

Enhanced option -extract_cut for handling filtered files

parent eea365ce
......@@ -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:
.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.
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
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,
......
#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,18 +7878,17 @@ int Xorriso_iso_file_open(struct XorrisO *xorriso, char *pathname,
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
ret= iso_stream_open(iso_stream);
if(ret<0) {
if(!iso_stream_is_repeatable(iso_stream)) {
sprintf(xorriso->info_text,
"Could not open data file in the image for reading");
"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);
}
if(!iso_stream_is_repeatable(iso_stream)) {
ret= iso_stream_open(iso_stream);
if(ret<0) {
sprintf(xorriso->info_text,
"The data production of the file in the image is one-time only");
"Could not open data file in the image for reading");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
iso_stream_close(iso_stream);
return(0);
}
Xorriso_process_msg_queues(xorriso,0);
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment