New -osirrox option sparse= controls extraction into sparse files

This commit is contained in:
Thomas Schmitt 2020-11-03 09:27:41 +01:00
parent 66fe150831
commit 05de7ec5ee
13 changed files with 464 additions and 82 deletions

View File

@ -473,6 +473,8 @@ int Xorriso_new(struct XorrisO ** xorriso,char *progname, int flag)
m->show_hfs_cmd_count= 0;
m->show_hfs_cmds= NULL;
m->sparse_min_gap= 0;
m->result_line[0]= 0;
m->result_line_counter= 0;
m->result_page_counter= 0;

View File

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -1367,3 +1367,18 @@ int Xorriso__format_guid(uint8_t guid[16], char *text, int flag)
return(1);
}
int Xorriso__parse_size_param(char *cpt, int key_l, int l, double *num)
{
char text[16];
*num= 0.0;
if(l <= key_l || l >= key_l + 16)
return(0);
strncpy(text, cpt + key_l, l - key_l);
text[l - key_l]= 0;
*num= Scanf_io_size(text, 0);
return(1);
}

View File

@ -1,11 +1,12 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2019 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
This file contains declarations of cellaneous helper functions of xorriso.
This file contains declarations of miscellaneous helper functions of
xorriso.
*/
@ -114,5 +115,13 @@ int Xorriso__exchange_prefix(char *source_prefix, char *target_prefix,
*/
int Xorriso__format_guid(uint8_t guid[16], char *text, int flag);
/* @param cpt start of keyword=value string
@param key_l length from cpt of keyword= string
@param l length from cpt up to end of value string
@param num result
*/
int Xorriso__parse_size_param(char *cpt, int key_l, int l, double *num);
#endif /* ! Xorriso_pvt_misc_includeD */

View File

@ -2308,6 +2308,7 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" [:\"sort_lba_on\"|\"sort_lba_off\"]",
" [:\"strict_acl_on\"|\"strict_acl_off\"]",
" [:\"check_md5_on\"|\"check_md5_off\"|\"check_md5_force\"]",
" [:\"sparse=off\"|\"sparse=\"number]",
" By default \"off\" the inverse operation of xorriso from ISO",
" image to disk filesystem is disabled. \"on\" allows xorriso",
" to create, overwrite, delete files in the disk filesystem.",

View File

@ -1746,6 +1746,7 @@ int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
{
int l, allow_restore;
char *npt, *cpt;
double num= 0.0;
allow_restore= xorriso->allow_restore;
@ -1799,6 +1800,21 @@ int Xorriso_option_osirrox(struct XorrisO *xorriso, char *mode, int flag)
xorriso->do_md5|= 3 << 6;
} else if(strncmp(cpt, "check_md5_off", l)==0 && l >= 13) {
xorriso->do_md5&= ~(3 << 6);
} else if(strncmp(cpt, "sparse=", 7) == 0 && l >= 7) {
if(strncmp(cpt + 7, "off", 3) == 0 && l == 10) {
num= 0.0;
} else {
Xorriso__parse_size_param(cpt, 7, l, &num);
if(num < 1.0)
num= 0.0;
if(num > 1.0 * 1024.0 * 1024.0 * 1024.0) {
strcpy(xorriso->info_text,
"osirrox sparse= too large (allowed: off, 1 to 1g)");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
}
xorriso->sparse_min_gap= num;
} else {
unknown_mode:;
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt);

View File

@ -147,8 +147,11 @@ int Xorriso_option_paste_in(struct XorrisO *xorriso, char *iso_rr_path,
(double) startbyte, (double) (startbyte+bytecount));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0);
Xorriso_pacifier_reset(xorriso, 0);
ret= Xorriso_paste_in(xorriso, disk_path, startbyte, bytecount,
iso_rr_path, 0);
Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count,
xorriso->pacifier_total, "", 1 | 4 | 8 | 32);
return(ret);
}
@ -2245,19 +2248,6 @@ int Xorriso_option_xattr(struct XorrisO *xorriso, char *mode, int flag)
}
static int parse_zisofs_param(char *cpt, int key_l, int l, double *num)
{
char text[16];
*num= 0.0;
if(l <= key_l || l >= key_l + 16)
return(0);
strncpy(text, cpt + key_l, l - key_l);
text[l - key_l]= 0;
*num= Scanf_io_size(text, 0);
return(1);
}
/* Option -zisofs */
int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
{
@ -2307,7 +2297,7 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
/* (ignored info from -status) */;
} else if(strncmp(cpt, "block_size=", 11)==0) {
parse_zisofs_param(cpt, 11, l, &num);
Xorriso__parse_size_param(cpt, 11, l, &num);
if (num != (1 << 15) && num != (1 << 16) && num != (1 << 17)) {
sprintf(xorriso->info_text,
"-zisofs: Unsupported block size (allowed 32k, 64k, 128k)");
@ -2342,7 +2332,7 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
}
} else if(strncmp(cpt, "max_bpt=", 8) == 0) {
parse_zisofs_param(cpt, 8, l, &num);
Xorriso__parse_size_param(cpt, 8, l, &num);
if(num < 1024.0 || num > 128.0 * 1024.0 * 1024.0 * 1024.0) {
sprintf(xorriso->info_text,
"-zisofs: Unsupported block pointer pool size (allowed: 1k to 128g)");
@ -2357,7 +2347,7 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
xorriso->zisofs_max_file_blocks= xorriso->zisofs_max_total_blocks;
} else if(strncmp(cpt, "max_bpt_f=", 10) == 0) {
parse_zisofs_param(cpt, 10, l, &num);
Xorriso__parse_size_param(cpt, 10, l, &num);
if(num < 1024.0 || num > 128.0 * 1024.0 * 1024.0 * 1024.0) {
sprintf(xorriso->info_text,
"-zisofs: Unsupported block pointer list size (allowed: 1k to 128g)");
@ -2368,7 +2358,7 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
xorriso->zisofs_max_total_blocks= xorriso->zisofs_max_file_blocks;
} else if(strncmp(cpt, "block_size_v2=", 14) == 0) {
parse_zisofs_param(cpt, 14, l, &num);
Xorriso__parse_size_param(cpt, 14, l, &num);
for(i= 15 ; i <= 20; i++)
if(num == (1 << i))
break;
@ -2380,11 +2370,11 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
xorriso->zisofs_v2_block_size= num;
} else if(strncmp(cpt, "bpt_target=", 11) == 0) {
parse_zisofs_param(cpt, 11, l, &num);
Xorriso__parse_size_param(cpt, 11, l, &num);
xorriso->zisofs_block_number_target= num;
} else if(strncmp(cpt, "bpt_free_ratio=", 15) == 0) {
parse_zisofs_param(cpt, 15, l, &num);
Xorriso__parse_size_param(cpt, 15, l, &num);
/* 0 means to libisofs "do not change" */
if(num == 0.0)
num= -1.0;

View File

@ -533,6 +533,278 @@ ex:;
}
/* If defined the position accounting will be done by lseek() and used to
* verify the position accounting in struct Xorriso_sparse_statE.
* # def ine Xorriso_check_sparsE yes
*/
struct Xorriso_sparse_statE {
int use_lseek;
off_t cur_pos;
off_t after_last_written;
int warnings;
};
#ifdef Xorriso_check_sparsE
static int Xorriso_sparse_warn(struct XorrisO *xorriso,
struct Xorriso_sparse_statE *sparse_state,
int occasion, char *msg, int flag)
{
if(sparse_state->warnings & (1 << occasion))
return(1);
sparse_state->warnings|= 1 << occasion;
Xorriso_msgs_submit(xorriso, 0, msg, 0, "SORRY", 0);
return(1);
}
#endif /* Xorriso_check_sparsE */
static int Xorriso_sparse_init(struct XorrisO *xorriso,
struct Xorriso_sparse_statE **sparse_state,
int write_fd, int flag)
{
struct Xorriso_sparse_statE *o= NULL;
off_t cur_pos;
struct stat stbuf;
int ret;
*sparse_state= NULL;
/* Check whether sparse writing is disabled */
if(xorriso->sparse_min_gap <= 0)
{ret= 0; goto ex;}
/* Analyze write_fd */
ret= fstat(write_fd, &stbuf);
if(ret == -1)
{ret= 0; goto ex;}
if(!S_ISREG(stbuf.st_mode))
{ret= 0; goto ex;}
cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
if(cur_pos < stbuf.st_size)
{ret= 0; goto ex;}
Xorriso_alloc_meM(o, struct Xorriso_sparse_statE, 1);
/* Initialize sparse_state */
o->use_lseek= 1;
o->cur_pos= o->after_last_written= cur_pos;
o->warnings= 0;
ret= 1;
ex:;
if(ret >= 1)
*sparse_state= o;
else
Xorriso_free_meM(o);
return(ret);
}
static int Xorriso_sparse_zeroize(struct XorrisO *xorriso,
struct Xorriso_sparse_statE *sparse_state,
int write_fd, off_t start, off_t count,
int flag)
{
int ret, buf_size= 32 * 1024, buf_fill, wret;
off_t todo, seek_ret;
char *buf= NULL;
if(count <= 0)
{ret= 2; goto ex;}
Xorriso_alloc_meM(buf, char, buf_size);
seek_ret= lseek(write_fd, start, SEEK_SET);
if(seek_ret == -1)
{ret= -1; goto ex;}
sparse_state->cur_pos= seek_ret;
for(todo= count; todo > 0; ) {
if(buf_size < todo)
buf_fill= buf_size;
else
buf_fill= todo;
wret= write(write_fd, buf, buf_fill);
if(wret <= 0)
{ret= wret; goto ex;}
todo-= wret;
sparse_state->cur_pos+= wret;
}
ret= 1;
ex:;
Xorriso_free_meM(buf);
return(ret);
}
/* @param flag bit0= this is the last buffer of the stream
*/
static int Xorriso_sparse_write(struct XorrisO *xorriso,
struct Xorriso_sparse_statE *sparse_state,
int write_fd, char *buf, int count,
int flag)
{
int wret, i, ret;
off_t cur_pos= -1, seek_ret;
static char zero[32]= {0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0};
if(sparse_state == NULL)
goto do_write;
if(!sparse_state->use_lseek)
goto do_write;
if(flag & 1)
goto do_write;
#ifdef Xorriso_check_sparsE
cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
if(cur_pos == -1)
goto do_write;
if(cur_pos != sparse_state->cur_pos) {
Xorriso_sparse_warn(xorriso, sparse_state, 0,
"cur_pos deviation in Xorriso_sparse_write:intro", 0);
sparse_state->cur_pos= cur_pos;
}
#else
cur_pos= sparse_state->cur_pos;
#endif
/* Check for all zeros */
if(count % 32)
goto do_write;
for(i= 0; i < count; i+= 32)
if(memcmp(buf + i, zero, 32))
break;
if(i < count)
goto do_write;
/* Omit write() until next non-zero buffer or end of writing */
#ifdef Xorriso_check_sparsE
/* Only for debugging: Do real lseek() instead of write() */
seek_ret= lseek(write_fd, cur_pos + count, SEEK_SET);
if(seek_ret == -1)
return(-1);
#endif
sparse_state->cur_pos= cur_pos + count;
return(count);
do_write:
if(sparse_state != NULL) {
/* Check whether the gap since after_last_written is too small.
If so: fill the whole gap by writing zeros.
*/
if(sparse_state->after_last_written < cur_pos) {
if(xorriso->sparse_min_gap > cur_pos - sparse_state->after_last_written) {
ret= Xorriso_sparse_zeroize(xorriso, sparse_state, write_fd,
sparse_state->after_last_written,
cur_pos - sparse_state->after_last_written, 0);
if(ret < 0)
return(ret);
if(ret == 0) {
seek_ret= lseek(write_fd, cur_pos, SEEK_SET);
if(seek_ret == -1)
return(-1);
sparse_state->cur_pos= seek_ret;
}
}
}
}
if(sparse_state != NULL) {
#ifdef Xorriso_check_sparsE
cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
if(cur_pos != sparse_state->cur_pos) {
Xorriso_sparse_warn(xorriso, sparse_state, 1,
"cur_pos deviation in Xorriso_sparse_write:do_write", 0);
sparse_state->cur_pos= cur_pos;
}
#else
/* lseek() has been delayed until now */
if(sparse_state->after_last_written != sparse_state->cur_pos) {
seek_ret= lseek(write_fd, sparse_state->cur_pos, SEEK_SET);
if(seek_ret == -1)
return(-1);
}
#endif /* ! Xorriso_check_sparsE */
}
wret= write(write_fd, buf, count);
if(sparse_state != NULL && wret > 0 && cur_pos >= 0)
sparse_state->cur_pos= sparse_state->after_last_written= cur_pos + wret;
return(wret);
}
static int Xorriso_sparse_finish(struct XorrisO *xorriso,
struct Xorriso_sparse_statE **sparse_state,
int write_fd, int flag)
{
int ret;
off_t cur_pos;
struct Xorriso_sparse_statE *o;
if(sparse_state == NULL)
return(0);
o= *sparse_state;
if(o == NULL)
return(1);
if(write_fd == -1)
{ret= 1; goto ex;}
#ifdef Xorriso_check_sparsE
cur_pos= lseek(write_fd, (off_t) 0, SEEK_CUR);
if(cur_pos == -1)
{ret= -1; goto ex;}
if(cur_pos != o->cur_pos) {
Xorriso_sparse_warn(xorriso, o, 2,
"cur_pos deviation in Xorriso_sparse_finish", 0);
o->cur_pos= cur_pos;
}
#else
cur_pos= o->cur_pos;
#endif /* ! Xorriso_check_sparsE */
if(o->after_last_written < cur_pos) {
/* Check whether the gap since after_last_written is too small.
If so: fill the whole gap by writing zeros, else: write a last zero byte.
*/
if(xorriso->sparse_min_gap > cur_pos - o->after_last_written)
ret= Xorriso_sparse_zeroize(xorriso, o, write_fd, o->after_last_written,
cur_pos - o->after_last_written, 0);
else
ret= Xorriso_sparse_zeroize(xorriso, o, write_fd, cur_pos - 1, (off_t) 1,
0);
if(ret <= 0)
goto ex;
}
ret= 1;
ex:;
Xorriso_free_meM(o);
*sparse_state= NULL;
return(ret);
}
/* @param flag bit0= Minimal transfer: access permissions only
bit1= *_offset and bytes are valid for writing to regular file
bit2= This is not a parameter. Do not report if ignored
@ -567,7 +839,8 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
off_t catsize;
char disk_md5[16], iso_md5[16];
void *ctx= NULL;
int use_md5= 0, i;
int use_md5= 0, i, sparse_ret= 3;
struct Xorriso_sparse_statE *sparse_state= NULL;
Xorriso_alloc_meM(buf, char, buf_size);
Xorriso_alloc_meM(temp_path, char, SfileadrL);
@ -679,6 +952,9 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
goto cannot_restore;
}
}
if(ISO_NODE_IS_FILE(node))
Xorriso_sparse_init(xorriso, &sparse_state, write_fd, 0);
while(todo>0) {
wanted= buf_size;
if(wanted>todo)
@ -731,7 +1007,11 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
ret= read_count - img_offset;
}
wret= write(write_fd, buf_pt, ret);
if(sparse_state == NULL)
wret= write(write_fd, buf_pt, ret);
else
wret= Xorriso_sparse_write(xorriso, sparse_state, write_fd, buf_pt, ret,
0);
if(wret>=0) {
todo-= wret;
xorriso->pacifier_byte_count+= wret;
@ -774,8 +1054,11 @@ bad_md5:;
}
}
}
if(write_fd != -1)
if(write_fd != -1) {
sparse_ret= Xorriso_sparse_finish(xorriso, &sparse_state, write_fd, 0);
close(write_fd);
}
write_fd= -1;
if(todo > 0 && xorriso->extract_error_mode == 2) {
unlink(open_path_pt);
@ -798,6 +1081,12 @@ bad_md5:;
}
ret= -(todo > 0);
l_errno= 0;
if(sparse_ret <= 0) {
strcpy(xorriso->info_text, "Could not finalize sparse extraction of ");
Text_shellsafe(disk_path, xorriso->info_text, 1 | 2);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text,
sparse_ret < 0 ? errno : 0, "FAILURE", 0);
}
} else if(LIBISO_ISLNK(node)) {
what= "symbolic link";
@ -898,6 +1187,8 @@ ex:;
Xorriso_iso_file_close(xorriso, &data_stream, 0);
if(ctx != NULL)
Xorriso_md5_end(xorriso, &ctx, disk_md5, 0);
if(sparse_state != NULL)
Xorriso_sparse_finish(xorriso, &sparse_state, -1, 0);
Xorriso_process_msg_queues(xorriso,0);
return(ret);
}

View File

@ -2990,18 +2990,29 @@ int Xorriso_status(struct XorrisO *xorriso, char *filter, FILE *fp, int flag)
if(xorriso->allow_restore == -1)
sprintf(line,"-osirrox %s\n", mode_pt);
else
sprintf(line,"-osirrox %s:%s:%s:%s:%s:%s:%s\n", mode_pt,
sprintf(line,"-osirrox %s:%s:%s:%s:%s\n", mode_pt,
xorriso->do_concat_split ? "concat_split_on" : "concat_split_off",
xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off",
xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_off",
xorriso->drives_exclusive ? "o_excl_on" : "o_excl_off",
xorriso->drives_exclusive ? "o_excl_on" : "o_excl_off");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
is_default = ((xorriso->do_strict_acl & 1) == 0 &&
(xorriso->do_md5 & (64 | 128)) == 0 &&
xorriso->sparse_min_gap == 0);
sprintf(line,"-osirrox %s:%s:sparse=",
(xorriso->do_strict_acl & 1) ? "strict_acl_on" : "strict_acl_off",
(xorriso->do_md5 & 64) ?
(xorriso->do_md5 & 128) ? "check_md5_force" : "check_md5_on"
: "check_md5_off"
);
: "check_md5_off");
if(xorriso->sparse_min_gap <= 0)
strcat(line, "off");
else
Sfile_off_t_text(line + strlen(line), xorriso->sparse_min_gap, 0);
strcat(line, "\n");
if(!(is_default && no_defaults))
Xorriso_status_result(xorriso,filter,fp,flag&2);
Xorriso_status_result(xorriso, filter, fp, flag & 2);
is_default= (xorriso->mount_opts_flag == 0);
sprintf(line,"-mount_opts %s\n",

View File

@ -9,7 +9,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 "Version 1.5.3, Oct 27, 2020"
.TH XORRISO 1 "Version 1.5.3, Nov 02, 2020"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -5004,6 +5004,21 @@ MD5 of the copied content gets computed and compared with the recorded MD5.
A mismatch causes an error message of severity SORRY.
Option \fBcheck_md5_force\fR causes an error message if \-md5 is "on"
but no MD5 is recorded for the data file.
.br
Option \fBsparse=\fR controls production of sparse files during
extraction of files from the ISO filesystem.
Default is \fBsparse=off\fR.
.br
A positive number like in \fBsparse=1m\fR sets the minimum requirement
for the length of a sequence of 0\-bytes which shall be represented by a gap.
This saves disk space if the disk filesystem supports sparse files.
A gap gets created by help of lseek(2) if a sequence of read buffers, which
contain only 0\-bytes, bears at least the minimum amount of bytes. Expect
read buffers to be in the size range of 32k or 64k.
.br
Command \-paste_in creates gaps only if the writing begins at or after the end
of the existing disk file. So the sequence of \-paste_in commands matters.
Command \-concat does not create sparse files.
.TP
\fB\-extract\fR iso_rr_path disk_path
Copy the file objects at and underneath iso_rr_path to their corresponding

View File

@ -4221,6 +4221,20 @@ The directory permissions on disk have to allow rwx.
compared with the recorded MD5. A mismatch causes an error message
of severity SORRY. Option *check_md5_force* causes an error message
if -md5 is "on" but no MD5 is recorded for the data file.
Option *sparse=* controls production of sparse files during
extraction of files from the ISO filesystem. Default is
*sparse=off*.
A positive number like in *sparse=1m* sets the minimum requirement
for the length of a sequence of 0-bytes which shall be represented
by a gap. This saves disk space if the disk filesystem supports
sparse files. A gap gets created by help of lseek(2) if a sequence
of read buffers, which contain only 0-bytes, bears at least the
minimum amount of bytes. Expect read buffers to be in the size
range of 32k or 64k.
Command -paste_in creates gaps only if the writing begins at or
after the end of the existing disk file. So the sequence of
-paste_in commands matters. Command -concat does not create sparse
files.
-extract iso_rr_path disk_path
Copy the file objects at and underneath iso_rr_path to their
corresponding addresses at and underneath disk_path. This is the
@ -5519,14 +5533,14 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -compare_l reports ISO/disk differences: Navigate. (line 147)
* -compare_r reports ISO/disk differences: Navigate. (line 143)
* -compliance controls standard compliance: SetWrite. (line 62)
* -concat copies ISO file content: Restore. (line 125)
* -concat copies ISO file content: Restore. (line 139)
* -copyright_file sets copyright file name: SetWrite. (line 245)
* -cpax copies files to disk: Restore. (line 107)
* -cpax copies files to disk: Restore. (line 121)
* -cpr inserts like with cp -r: Insert. (line 164)
* -cpx copies files to disk: Restore. (line 96)
* -cpx copies files to disk: Restore. (line 110)
* -cp_clone copies ISO directory tree: Insert. (line 196)
* -cp_rx copies file trees to disk: Restore. (line 110)
* -cp_rx copies file trees to disk <1>: Restore. (line 118)
* -cp_rx copies file trees to disk: Restore. (line 124)
* -cp_rx copies file trees to disk <1>: Restore. (line 132)
* -cut_out inserts piece of data file: Insert. (line 139)
* -data_cache_size adjusts read cache size: Loading. (line 353)
* -dev acquires one drive for input and output: AqDrive. (line 12)
@ -5553,10 +5567,10 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -error_behavior controls error workarounds: Exception. (line 92)
* -external_filter registers data filter: Filter. (line 20)
* -external_filter unregisters data filter: Filter. (line 47)
* -extract copies file tree to disk: Restore. (line 69)
* -extract_cut copies file piece to disk: Restore. (line 87)
* -extract_l copies files to disk: Restore. (line 83)
* -extract_single copies file to disk: Restore. (line 80)
* -extract copies file tree to disk: Restore. (line 83)
* -extract_cut copies file piece to disk: Restore. (line 101)
* -extract_l copies files to disk: Restore. (line 97)
* -extract_single copies file to disk: Restore. (line 94)
* -file_name_limit curbs length of file names: Loading. (line 267)
* -file_size_limit limits data file size: SetInsert. (line 7)
* -find traverses and alters ISO tree: CmdFind. (line 7)
@ -5610,7 +5624,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -md5 controls handling of MD5 sums: Loading. (line 184)
* -mkdir creates ISO directory: Insert. (line 177)
* -modesty_on_drive keep drive buffer hungry: SetWrite. (line 406)
* -mount issues mount command for ISO session: Restore. (line 153)
* -mount issues mount command for ISO session: Restore. (line 167)
* -mount_cmd composes mount command line: Inquiry. (line 49)
* -mount_cmd controls mount command: Inquiry. (line 65)
* -msg_op perform operations on program messages: Frontend. (line 27)
@ -5630,7 +5644,7 @@ File: xorriso.info, Node: CommandIdx, Next: ConceptIdx, Prev: Legal, Up: Top
* -pacifier controls pacifier text form: Emulation. (line 166)
* -padding sets amount or mode of image padding: SetWrite. (line 494)
* -page set terminal geometry: DialogCtl. (line 18)
* -paste_in copies file into disk file: Restore. (line 121)
* -paste_in copies file into disk file: Restore. (line 135)
* -pathspecs sets meaning of = with -add: SetInsert. (line 115)
* -path_list inserts paths from disk file: Insert. (line 81)
* -pkt_output consolidates text output: Frontend. (line 7)
@ -5803,7 +5817,7 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Emulation, pacifier form, -pacifier: Emulation. (line 166)
* Examples: Examples. (line 6)
* extattr, _definition: Extras. (line 66)
* File content, copy, -concat: Restore. (line 125)
* File content, copy, -concat: Restore. (line 139)
* File names, curb length, -file_name_limit: Loading. (line 267)
* File names, if neither Rock Ridge nor Joliet: Loading. (line 229)
* Filter, apply to file tree, -set_filter_r: Filter. (line 84)
@ -5966,22 +5980,22 @@ File: xorriso.info, Node: ConceptIdx, Prev: CommandIdx, Up: Top
* Relocation directory, set name, -rr_reloc_dir: SetWrite. (line 150)
* Rename, in ISO image, -move: Manip. (line 31)
* Rename, in ISO image, -mv: Manip. (line 37)
* Restore, copy file into disk file, -paste_in: Restore. (line 121)
* Restore, copy file piece to disk, -extract_cut: Restore. (line 87)
* Restore, copy file to disk, -extract_single: Restore. (line 80)
* Restore, copy file tree to disk, -extract: Restore. (line 69)
* Restore, copy file trees to disk, -cp_rx: Restore. (line 110)
* Restore, copy file trees to disk, -cp_rx <1>: Restore. (line 118)
* Restore, copy files to disk, -cpax: Restore. (line 107)
* Restore, copy files to disk, -cpx: Restore. (line 96)
* Restore, copy files to disk, -extract_l: Restore. (line 83)
* Restore, copy file into disk file, -paste_in: Restore. (line 135)
* Restore, copy file piece to disk, -extract_cut: Restore. (line 101)
* Restore, copy file to disk, -extract_single: Restore. (line 94)
* Restore, copy file tree to disk, -extract: Restore. (line 83)
* Restore, copy file trees to disk, -cp_rx: Restore. (line 124)
* Restore, copy file trees to disk, -cp_rx <1>: Restore. (line 132)
* Restore, copy files to disk, -cpax: Restore. (line 121)
* Restore, copy files to disk, -cpx: Restore. (line 110)
* Restore, copy files to disk, -extract_l: Restore. (line 97)
* Restore, enable ISO-to-disk, -osirrox: Restore. (line 18)
* Result layout, more shell-like, -sh_style_result: Scripting.
(line 61)
* Rock Ridge, _definition: Extras. (line 6)
* Session, altered start address, -displacement: Loading. (line 78)
* Session, info string, -session_string: Inquiry. (line 74)
* Session, issue mount command, -mount: Restore. (line 153)
* Session, issue mount command, -mount: Restore. (line 167)
* Session, log when written, -session_log: Scripting. (line 134)
* Session, mount command line, -mount_cmd: Inquiry. (line 49)
* Session, mount parameters, -mount_opts: Inquiry. (line 65)
@ -6066,32 +6080,32 @@ Node: Inquiry197292
Node: Navigate206174
Node: Verify214881
Node: Restore226030
Node: Emulation235196
Node: Scripting245652
Node: Frontend253435
Node: Examples263061
Node: ExDevices264239
Node: ExCreate264900
Node: ExDialog266200
Node: ExGrowing267471
Node: ExModifying268280
Node: ExBootable268790
Node: ExCharset269345
Node: ExPseudo270241
Node: ExCdrecord271168
Node: ExMkisofs271488
Node: ExGrowisofs273385
Node: ExException274538
Node: ExTime274996
Node: ExIncBackup275454
Node: ExRestore279480
Node: ExRecovery280426
Node: Files280998
Node: Environ282332
Node: Seealso283080
Node: Bugreport283797
Node: Legal284388
Node: CommandIdx285400
Node: ConceptIdx303016
Node: Emulation236013
Node: Scripting246469
Node: Frontend254252
Node: Examples263878
Node: ExDevices265056
Node: ExCreate265717
Node: ExDialog267017
Node: ExGrowing268288
Node: ExModifying269097
Node: ExBootable269607
Node: ExCharset270162
Node: ExPseudo271058
Node: ExCdrecord271985
Node: ExMkisofs272305
Node: ExGrowisofs274202
Node: ExException275355
Node: ExTime275813
Node: ExIncBackup276271
Node: ExRestore280297
Node: ExRecovery281243
Node: Files281815
Node: Environ283149
Node: Seealso283897
Node: Bugreport284614
Node: Legal285205
Node: CommandIdx286217
Node: ConceptIdx303833

End Tag Table

View File

@ -50,7 +50,7 @@
@c man .\" First parameter, NAME, should be all caps
@c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
@c man .\" other parameters are allowed: see man(7), man(1)
@c man .TH XORRISO 1 "Version 1.5.3, Oct 27, 2020"
@c man .TH XORRISO 1 "Version 1.5.3, Nov 02, 2020"
@c man .\" Please adjust this date whenever revising the manpage.
@c man .\"
@c man .\" Some roff macros, for reference:
@ -5739,6 +5739,21 @@ MD5 of the copied content gets computed and compared with the recorded MD5.
A mismatch causes an error message of severity SORRY.
Option @strong{check_md5_force} causes an error message if -md5 is "on"
but no MD5 is recorded for the data file.
@*
Option @strong{sparse=} controls production of sparse files during
extraction of files from the ISO filesystem.
Default is @strong{sparse=off}.
@*
A positive number like in @strong{sparse=1m} sets the minimum requirement
for the length of a sequence of 0-bytes which shall be represented by a gap.
This saves disk space if the disk filesystem supports sparse files.
A gap gets created by help of lseek(2) if a sequence of read buffers, which
contain only 0-bytes, bears at least the minimum amount of bytes. Expect
read buffers to be in the size range of 32k or 64k.
@*
Command -paste_in creates gaps only if the writing begins at or after the end
of the existing disk file. So the sequence of -paste_in commands matters.
Command -concat does not create sparse files.
@c man .TP
@item -extract iso_rr_path disk_path
@kindex -extract copies file tree to disk

View File

@ -864,6 +864,9 @@ struct XorrisO { /* the global context of xorriso */
int show_hfs_cmd_count;
char **show_hfs_cmds;
/* Extraction to sparse files */
off_t sparse_min_gap;
/* result (stdout, R: ) */
char result_line[10*SfileadrL];
int result_line_counter;

View File

@ -1 +1 @@
#define Xorriso_timestamP "2020.10.31.195038"
#define Xorriso_timestamP "2020.11.03.082729"