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_cmd_count= 0;
m->show_hfs_cmds= NULL; m->show_hfs_cmds= NULL;
m->sparse_min_gap= 0;
m->result_line[0]= 0; m->result_line[0]= 0;
m->result_line_counter= 0; m->result_line_counter= 0;
m->result_page_counter= 0; m->result_page_counter= 0;

View File

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images. /* 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. 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); 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. /* 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. 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); 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 */ #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\"]", " [:\"sort_lba_on\"|\"sort_lba_off\"]",
" [:\"strict_acl_on\"|\"strict_acl_off\"]", " [:\"strict_acl_on\"|\"strict_acl_off\"]",
" [:\"check_md5_on\"|\"check_md5_off\"|\"check_md5_force\"]", " [:\"check_md5_on\"|\"check_md5_off\"|\"check_md5_force\"]",
" [:\"sparse=off\"|\"sparse=\"number]",
" By default \"off\" the inverse operation of xorriso from ISO", " By default \"off\" the inverse operation of xorriso from ISO",
" image to disk filesystem is disabled. \"on\" allows xorriso", " image to disk filesystem is disabled. \"on\" allows xorriso",
" to create, overwrite, delete files in the disk filesystem.", " 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; int l, allow_restore;
char *npt, *cpt; char *npt, *cpt;
double num= 0.0;
allow_restore= xorriso->allow_restore; 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; xorriso->do_md5|= 3 << 6;
} else if(strncmp(cpt, "check_md5_off", l)==0 && l >= 13) { } else if(strncmp(cpt, "check_md5_off", l)==0 && l >= 13) {
xorriso->do_md5&= ~(3 << 6); 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 { } else {
unknown_mode:; unknown_mode:;
sprintf(xorriso->info_text, "-osirrox: unknown mode '%s'", cpt); 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)); (double) startbyte, (double) (startbyte+bytecount));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "DEBUG", 0); 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, ret= Xorriso_paste_in(xorriso, disk_path, startbyte, bytecount,
iso_rr_path, 0); iso_rr_path, 0);
Xorriso_pacifier_callback(xorriso, "files restored",xorriso->pacifier_count,
xorriso->pacifier_total, "", 1 | 4 | 8 | 32);
return(ret); 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 */ /* Option -zisofs */
int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag) 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) */; /* (ignored info from -status) */;
} else if(strncmp(cpt, "block_size=", 11)==0) { } 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)) { if (num != (1 << 15) && num != (1 << 16) && num != (1 << 17)) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"-zisofs: Unsupported block size (allowed 32k, 64k, 128k)"); "-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) { } 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) { if(num < 1024.0 || num > 128.0 * 1024.0 * 1024.0 * 1024.0) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"-zisofs: Unsupported block pointer pool size (allowed: 1k to 128g)"); "-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; xorriso->zisofs_max_file_blocks= xorriso->zisofs_max_total_blocks;
} else if(strncmp(cpt, "max_bpt_f=", 10) == 0) { } 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) { if(num < 1024.0 || num > 128.0 * 1024.0 * 1024.0 * 1024.0) {
sprintf(xorriso->info_text, sprintf(xorriso->info_text,
"-zisofs: Unsupported block pointer list size (allowed: 1k to 128g)"); "-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; xorriso->zisofs_max_total_blocks= xorriso->zisofs_max_file_blocks;
} else if(strncmp(cpt, "block_size_v2=", 14) == 0) { } 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++) for(i= 15 ; i <= 20; i++)
if(num == (1 << i)) if(num == (1 << i))
break; break;
@ -2380,11 +2370,11 @@ int Xorriso_option_zisofs(struct XorrisO *xorriso, char *mode, int flag)
xorriso->zisofs_v2_block_size= num; xorriso->zisofs_v2_block_size= num;
} else if(strncmp(cpt, "bpt_target=", 11) == 0) { } 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; xorriso->zisofs_block_number_target= num;
} else if(strncmp(cpt, "bpt_free_ratio=", 15) == 0) { } 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" */ /* 0 means to libisofs "do not change" */
if(num == 0.0) if(num == 0.0)
num= -1.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 /* @param flag bit0= Minimal transfer: access permissions only
bit1= *_offset and bytes are 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 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; off_t catsize;
char disk_md5[16], iso_md5[16]; char disk_md5[16], iso_md5[16];
void *ctx= NULL; 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(buf, char, buf_size);
Xorriso_alloc_meM(temp_path, char, SfileadrL); Xorriso_alloc_meM(temp_path, char, SfileadrL);
@ -679,6 +952,9 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
goto cannot_restore; goto cannot_restore;
} }
} }
if(ISO_NODE_IS_FILE(node))
Xorriso_sparse_init(xorriso, &sparse_state, write_fd, 0);
while(todo>0) { while(todo>0) {
wanted= buf_size; wanted= buf_size;
if(wanted>todo) if(wanted>todo)
@ -731,7 +1007,11 @@ int Xorriso_tree_restore_node(struct XorrisO *xorriso, IsoNode *node,
ret= read_count - img_offset; 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) { if(wret>=0) {
todo-= wret; todo-= wret;
xorriso->pacifier_byte_count+= 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); close(write_fd);
}
write_fd= -1; write_fd= -1;
if(todo > 0 && xorriso->extract_error_mode == 2) { if(todo > 0 && xorriso->extract_error_mode == 2) {
unlink(open_path_pt); unlink(open_path_pt);
@ -798,6 +1081,12 @@ bad_md5:;
} }
ret= -(todo > 0); ret= -(todo > 0);
l_errno= 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)) { } else if(LIBISO_ISLNK(node)) {
what= "symbolic link"; what= "symbolic link";
@ -898,6 +1187,8 @@ ex:;
Xorriso_iso_file_close(xorriso, &data_stream, 0); Xorriso_iso_file_close(xorriso, &data_stream, 0);
if(ctx != NULL) if(ctx != NULL)
Xorriso_md5_end(xorriso, &ctx, disk_md5, 0); 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); Xorriso_process_msg_queues(xorriso,0);
return(ret); 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) if(xorriso->allow_restore == -1)
sprintf(line,"-osirrox %s\n", mode_pt); sprintf(line,"-osirrox %s\n", mode_pt);
else 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_concat_split ? "concat_split_on" : "concat_split_off",
xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off", xorriso->do_auto_chmod ? "auto_chmod_on" : "auto_chmod_off",
xorriso->do_restore_sort_lba ? "sort_lba_on" : "sort_lba_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_strict_acl & 1) ? "strict_acl_on" : "strict_acl_off",
(xorriso->do_md5 & 64) ? (xorriso->do_md5 & 64) ?
(xorriso->do_md5 & 128) ? "check_md5_force" : "check_md5_on" (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)) 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); is_default= (xorriso->mount_opts_flag == 0);
sprintf(line,"-mount_opts %s\n", sprintf(line,"-mount_opts %s\n",

View File

@ -9,7 +9,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 "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. .\" Please adjust this date whenever revising the manpage.
.\" .\"
.\" Some roff macros, for reference: .\" 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. A mismatch causes an error message of severity SORRY.
Option \fBcheck_md5_force\fR causes an error message if \-md5 is "on" Option \fBcheck_md5_force\fR causes an error message if \-md5 is "on"
but no MD5 is recorded for the data file. 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 .TP
\fB\-extract\fR iso_rr_path disk_path \fB\-extract\fR iso_rr_path disk_path
Copy the file objects at and underneath iso_rr_path to their corresponding 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 compared with the recorded MD5. A mismatch causes an error message
of severity SORRY. Option *check_md5_force* 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. 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 -extract iso_rr_path disk_path
Copy the file objects at and underneath iso_rr_path to their Copy the file objects at and underneath iso_rr_path to their
corresponding addresses at and underneath disk_path. This is the 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_l reports ISO/disk differences: Navigate. (line 147)
* -compare_r reports ISO/disk differences: Navigate. (line 143) * -compare_r reports ISO/disk differences: Navigate. (line 143)
* -compliance controls standard compliance: SetWrite. (line 62) * -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) * -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) * -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_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: Restore. (line 124)
* -cp_rx copies file trees to disk <1>: Restore. (line 118) * -cp_rx copies file trees to disk <1>: Restore. (line 132)
* -cut_out inserts piece of data file: Insert. (line 139) * -cut_out inserts piece of data file: Insert. (line 139)
* -data_cache_size adjusts read cache size: Loading. (line 353) * -data_cache_size adjusts read cache size: Loading. (line 353)
* -dev acquires one drive for input and output: AqDrive. (line 12) * -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) * -error_behavior controls error workarounds: Exception. (line 92)
* -external_filter registers data filter: Filter. (line 20) * -external_filter registers data filter: Filter. (line 20)
* -external_filter unregisters data filter: Filter. (line 47) * -external_filter unregisters data filter: Filter. (line 47)
* -extract copies file tree to disk: Restore. (line 69) * -extract copies file tree to disk: Restore. (line 83)
* -extract_cut copies file piece to disk: Restore. (line 87) * -extract_cut copies file piece to disk: Restore. (line 101)
* -extract_l copies files to disk: Restore. (line 83) * -extract_l copies files to disk: Restore. (line 97)
* -extract_single copies file to disk: Restore. (line 80) * -extract_single copies file to disk: Restore. (line 94)
* -file_name_limit curbs length of file names: Loading. (line 267) * -file_name_limit curbs length of file names: Loading. (line 267)
* -file_size_limit limits data file size: SetInsert. (line 7) * -file_size_limit limits data file size: SetInsert. (line 7)
* -find traverses and alters ISO tree: CmdFind. (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) * -md5 controls handling of MD5 sums: Loading. (line 184)
* -mkdir creates ISO directory: Insert. (line 177) * -mkdir creates ISO directory: Insert. (line 177)
* -modesty_on_drive keep drive buffer hungry: SetWrite. (line 406) * -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 composes mount command line: Inquiry. (line 49)
* -mount_cmd controls mount command: Inquiry. (line 65) * -mount_cmd controls mount command: Inquiry. (line 65)
* -msg_op perform operations on program messages: Frontend. (line 27) * -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) * -pacifier controls pacifier text form: Emulation. (line 166)
* -padding sets amount or mode of image padding: SetWrite. (line 494) * -padding sets amount or mode of image padding: SetWrite. (line 494)
* -page set terminal geometry: DialogCtl. (line 18) * -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) * -pathspecs sets meaning of = with -add: SetInsert. (line 115)
* -path_list inserts paths from disk file: Insert. (line 81) * -path_list inserts paths from disk file: Insert. (line 81)
* -pkt_output consolidates text output: Frontend. (line 7) * -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) * Emulation, pacifier form, -pacifier: Emulation. (line 166)
* Examples: Examples. (line 6) * Examples: Examples. (line 6)
* extattr, _definition: Extras. (line 66) * 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, curb length, -file_name_limit: Loading. (line 267)
* File names, if neither Rock Ridge nor Joliet: Loading. (line 229) * File names, if neither Rock Ridge nor Joliet: Loading. (line 229)
* Filter, apply to file tree, -set_filter_r: Filter. (line 84) * 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) * Relocation directory, set name, -rr_reloc_dir: SetWrite. (line 150)
* Rename, in ISO image, -move: Manip. (line 31) * Rename, in ISO image, -move: Manip. (line 31)
* Rename, in ISO image, -mv: Manip. (line 37) * Rename, in ISO image, -mv: Manip. (line 37)
* Restore, copy file into disk file, -paste_in: Restore. (line 121) * Restore, copy file into disk file, -paste_in: Restore. (line 135)
* Restore, copy file piece to disk, -extract_cut: Restore. (line 87) * Restore, copy file piece to disk, -extract_cut: Restore. (line 101)
* Restore, copy file to disk, -extract_single: Restore. (line 80) * Restore, copy file to disk, -extract_single: Restore. (line 94)
* Restore, copy file tree to disk, -extract: Restore. (line 69) * Restore, copy file tree to disk, -extract: Restore. (line 83)
* Restore, copy file trees to disk, -cp_rx: Restore. (line 110) * Restore, copy file trees to disk, -cp_rx: Restore. (line 124)
* Restore, copy file trees to disk, -cp_rx <1>: Restore. (line 118) * Restore, copy file trees to disk, -cp_rx <1>: Restore. (line 132)
* Restore, copy files to disk, -cpax: Restore. (line 107) * Restore, copy files to disk, -cpax: Restore. (line 121)
* Restore, copy files to disk, -cpx: Restore. (line 96) * Restore, copy files to disk, -cpx: Restore. (line 110)
* Restore, copy files to disk, -extract_l: Restore. (line 83) * Restore, copy files to disk, -extract_l: Restore. (line 97)
* Restore, enable ISO-to-disk, -osirrox: Restore. (line 18) * Restore, enable ISO-to-disk, -osirrox: Restore. (line 18)
* Result layout, more shell-like, -sh_style_result: Scripting. * Result layout, more shell-like, -sh_style_result: Scripting.
(line 61) (line 61)
* Rock Ridge, _definition: Extras. (line 6) * Rock Ridge, _definition: Extras. (line 6)
* Session, altered start address, -displacement: Loading. (line 78) * Session, altered start address, -displacement: Loading. (line 78)
* Session, info string, -session_string: Inquiry. (line 74) * 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, log when written, -session_log: Scripting. (line 134)
* Session, mount command line, -mount_cmd: Inquiry. (line 49) * Session, mount command line, -mount_cmd: Inquiry. (line 49)
* Session, mount parameters, -mount_opts: Inquiry. (line 65) * Session, mount parameters, -mount_opts: Inquiry. (line 65)
@ -6066,32 +6080,32 @@ Node: Inquiry197292
Node: Navigate206174 Node: Navigate206174
Node: Verify214881 Node: Verify214881
Node: Restore226030 Node: Restore226030
Node: Emulation235196 Node: Emulation236013
Node: Scripting245652 Node: Scripting246469
Node: Frontend253435 Node: Frontend254252
Node: Examples263061 Node: Examples263878
Node: ExDevices264239 Node: ExDevices265056
Node: ExCreate264900 Node: ExCreate265717
Node: ExDialog266200 Node: ExDialog267017
Node: ExGrowing267471 Node: ExGrowing268288
Node: ExModifying268280 Node: ExModifying269097
Node: ExBootable268790 Node: ExBootable269607
Node: ExCharset269345 Node: ExCharset270162
Node: ExPseudo270241 Node: ExPseudo271058
Node: ExCdrecord271168 Node: ExCdrecord271985
Node: ExMkisofs271488 Node: ExMkisofs272305
Node: ExGrowisofs273385 Node: ExGrowisofs274202
Node: ExException274538 Node: ExException275355
Node: ExTime274996 Node: ExTime275813
Node: ExIncBackup275454 Node: ExIncBackup276271
Node: ExRestore279480 Node: ExRestore280297
Node: ExRecovery280426 Node: ExRecovery281243
Node: Files280998 Node: Files281815
Node: Environ282332 Node: Environ283149
Node: Seealso283080 Node: Seealso283897
Node: Bugreport283797 Node: Bugreport284614
Node: Legal284388 Node: Legal285205
Node: CommandIdx285400 Node: CommandIdx286217
Node: ConceptIdx303016 Node: ConceptIdx303833
 
End Tag Table End Tag Table

View File

@ -50,7 +50,7 @@
@c man .\" First parameter, NAME, should be all caps @c man .\" First parameter, NAME, should be all caps
@c man .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection @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 .\" 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 .\" Please adjust this date whenever revising the manpage.
@c man .\" @c man .\"
@c man .\" Some roff macros, for reference: @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. A mismatch causes an error message of severity SORRY.
Option @strong{check_md5_force} causes an error message if -md5 is "on" Option @strong{check_md5_force} causes an error message if -md5 is "on"
but no MD5 is recorded for the data file. 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 @c man .TP
@item -extract iso_rr_path disk_path @item -extract iso_rr_path disk_path
@kindex -extract copies file tree to disk @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; int show_hfs_cmd_count;
char **show_hfs_cmds; char **show_hfs_cmds;
/* Extraction to sparse files */
off_t sparse_min_gap;
/* result (stdout, R: ) */ /* result (stdout, R: ) */
char result_line[10*SfileadrL]; char result_line[10*SfileadrL];
int result_line_counter; int result_line_counter;

View File

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