New command -extract_boot_images

master
Thomas Schmitt 2 years ago
parent e97cd48ee0
commit 47be075c45
  1. 1
      libisoburn/libisoburn.ver
  2. 9
      xorriso/check_media.c
  3. 3
      xorriso/check_media.h
  4. 62
      xorriso/drive_mgt.c
  5. 300
      xorriso/iso_img.c
  6. 21
      xorriso/opts_d_h.c
  7. 15
      xorriso/parse_exec.c
  8. 153
      xorriso/read_run.c
  9. 28
      xorriso/sfile.c
  10. 3
      xorriso/sfile.h
  11. 39
      xorriso/xorriso.1
  12. 5
      xorriso/xorriso.h
  13. 90
      xorriso/xorriso.info
  14. 41
      xorriso/xorriso.texi
  15. 2
      xorriso/xorriso_timestamp.h
  16. 8
      xorriso/xorrisoburn.h

@ -221,6 +221,7 @@ Xorriso_option_errfile_log;
Xorriso_option_error_behavior;
Xorriso_option_external_filter;
Xorriso_option_extract;
Xorriso_option_extract_boot_images;
Xorriso_option_extract_cut;
Xorriso_option_file_name_limit;
Xorriso_option_file_size_limit;

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2015 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -587,6 +587,7 @@ int Checkmediajob_new(struct CheckmediajoB **o, int flag)
m->data_to_fd= -1;
m->data_to_offset= 0;
m->data_to_limit= -1;
m->data_to_skip= 0;
m->patch_lba0= 0;
m->patch_lba0_msc1= -1;
m->sector_map_path[0]= 0;
@ -604,7 +605,7 @@ int Checkmediajob_destroy(struct CheckmediajoB **o, int flag)
{
if((*o) == NULL)
return(0);
if((*o)->data_to_fd != -1 && strcmp((*o)->data_to_path, "-") == 0)
if((*o)->data_to_fd != -1 && strcmp((*o)->data_to_path, "-") != 0)
close((*o)->data_to_fd);
Sectorbitmap_destroy(&((*o)->sector_map), 0);
free((char *) *o);
@ -628,6 +629,7 @@ int Checkmediajob_copy(struct CheckmediajoB *from, struct CheckmediajoB *to,
/* not copied: data_to_fd */
to->data_to_offset= from->data_to_offset;
to->data_to_limit= from->data_to_limit;
to->data_to_skip= from->data_to_skip;
to->patch_lba0= from->patch_lba0;
to->patch_lba0_msc1= from->patch_lba0_msc1;
strcpy(to->sector_map_path, from->sector_map_path);
@ -1086,7 +1088,8 @@ int Xorriso_open_job_data_to(struct XorrisO *xorriso,
job->data_to_fd= 1;
} else {
job->data_to_fd= open(job->data_to_path, O_RDWR | O_CREAT | O_BINARY,
S_IRUSR | S_IWUSR);
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
S_IROTH | S_IWOTH);
}
if(job->data_to_fd == -1) {
sprintf(xorriso->info_text, "Cannot open path ");

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2011 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -118,6 +118,7 @@ struct CheckmediajoB {
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 data_to_skip; /* number of bytes to skip on writing. < 2048 */
int patch_lba0;
int patch_lba0_msc1;

@ -2792,7 +2792,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
{
int i, j, ret, total_count= 0, sectors= -1, sector_size= -1, skip_reading;
int prev_quality= -1, quality= -1, retry= 0, profile_no, is_cd= 0;
int eccb_size= 16, us_corr = 0;
int eccb_size= 16, us_corr = 0, data_skip;
int start_sec, end_sec, first_value, fret, suspect_tao_end= 0;
char profile_name[80];
int start_lba= 0;
@ -2800,7 +2800,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
struct burn_drive_info *dinfo;
char *data= NULL, *data_pt;
off_t data_count, to_read, read_count= 0, write_amount, skipped_to_read;
off_t slowdown_count= 0;
off_t slowdown_count= 0, seek_adr;
struct timeval prev_time;
double pre_read_time, post_read_time, time_diff, total_time_diff= 0;
double last_abort_file_time= 0;
@ -2823,6 +2823,7 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
else if(read_chunk < 1)
read_chunk= 1;
data_skip= job->data_to_skip;
num_chunks= job->async_chunks;
if(((off_t) num_chunks) * ((off_t) read_chunk) > chunks_limit)
num_chunks= chunks_limit / read_chunk;
@ -2923,6 +2924,8 @@ int Xorriso_check_interval(struct XorrisO *xorriso, struct SpotlisT *spotlist,
to_read= read_chunk;
post_read_time= Sfile_microtime(0);
for(i= 0; i < block_count; i+= to_read) {
if(i != 0)
data_skip= 0;
skip_reading= 0;
ret= Xorriso_check_for_abort(xorriso, job->abort_file_path, post_read_time,
&last_abort_file_time, 0);
@ -3069,9 +3072,9 @@ abort_check:;
}
}
write_amount= data_count;
write_amount= data_count - data_skip;
if(data_count > 0) {
read_count+= data_count;
read_count+= data_count - data_skip;
if(job->data_to_limit >= 0 && read_count > job->data_to_limit)
write_amount-= (read_count - job->data_to_limit);
}
@ -3086,21 +3089,22 @@ abort_check:;
}
if(write_amount > 0) {
if(job->data_to_fd >= 0) {
ret= 0;
if(strcmp(job->data_to_path, "-") != 0)
ret= lseek(job->data_to_fd,
((off_t) (i + from_lba)) * (off_t) 2048 + job->data_to_offset,
SEEK_SET);
if(ret == -1) {
seek_adr= ((off_t) (i + from_lba)) * (off_t) 2048 +
job->data_to_skip + job->data_to_offset;
if(strcmp(job->data_to_path, "-") != 0) {
ret= lseek(job->data_to_fd, seek_adr, SEEK_SET);
if(ret == -1) {
failed_to_write:;
sprintf(xorriso->info_text, "Cannot write %d bytes to lba %d of ",
(int) data_count, i + from_lba);
Text_shellsafe(job->data_to_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
"FAILURE", 0);
{ret= 0; goto ex;}
sprintf(xorriso->info_text,
"Cannot write %d bytes to position %.f in ",
(int) data_count, (double) seek_adr);
Text_shellsafe(job->data_to_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno,
"FAILURE", 0);
{ret= 0; goto ex;}
}
}
ret= write(job->data_to_fd, data_pt, write_amount);
ret= write(job->data_to_fd, data_pt + data_skip, write_amount);
if(ret == -1)
goto failed_to_write;
}
@ -3580,3 +3584,27 @@ int Xorriso_use_immed_bit(struct XorrisO *xorriso, int flag)
}
int Xorriso_obtain_indev_readsize(struct XorrisO *xorriso, uint32_t *blocks,
int flag)
{
int ret, num_data;
struct burn_drive_info *dinfo;
struct burn_drive *drive;
enum burn_disc_status s;
*blocks= 0;
ret= Xorriso_get_drive_handles(xorriso, &dinfo, &drive,
"on attempt to determine readable size", 0);
if(ret <= 0)
return(0);
s= isoburn_disc_get_status(drive);
if(s == BURN_DISC_BLANK)
return(1);
ret= burn_get_read_capacity(drive, &num_data, 0);
if(ret <= 0)
return(0);
*blocks= num_data;
return(1);
}

@ -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.
@ -1538,11 +1538,22 @@ int Xorriso_add_intvl_adr(struct XorrisO *xorriso, char *buf,
}
int Xorriso_add_offset_size(struct XorrisO *xorriso, char *buf,
off_t byte_offset, off_t byte_size, int flag)
{
strcat(buf, " ");
Sfile_off_t_text(buf + strlen(buf), byte_offset, 0);
strcat(buf, " ");
Sfile_off_t_text(buf + strlen(buf), byte_size, 0);
return(1);
}
struct elto_img_par {
int n, ldsiz, boot_info_table, grub2_boot_info;
int do_gpt_basdat, do_gpt_hfsplus, do_apm_hfsplus;
unsigned int ld_seg, hdpt, platform_id;
unsigned long int lba;
unsigned long int lba, extract_size;
char pltf[8], b[8], emul[8], boot_image_type[16];
char *path, *id_string, *sel_crit;
};
@ -1644,11 +1655,14 @@ ex:;
/* @param flag bit0= do not record but only count
bit1= as_mkisofs
bit2= no sorry messages
*/
static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
char **et_lines, int et_line_count,
char **sa_lines, int sa_line_count,
char **cmds, int *cmd_count, int flag)
char **cmds, int *cmd_count,
char **boot_imgs, int *boot_img_count,
int flag)
{
int ret= 0, i, num_count, mkisofs, line_count, idx, et_idx, isohybrid= 0;
int ptype, gpt_idx, j, pad, mbr_idx;
@ -1664,16 +1678,17 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
int iso_mbr_part_type= -1, iso_gpt_part_idx= -1;
unsigned int prev_pltf= 0;
unsigned long int sa_options= 0, partno, id_tag, perms, start_cyl, num_blocks;
unsigned long int part_status, part_type, start_block, partition_offset= 0;
uint32_t high_block= 0;
unsigned long int sa_options= 0, partno, id_tag, perms, start_cyl;
unsigned long int part_status, part_type, mbr_start_block, mbr_num_blocks;
unsigned long int partition_offset= 0;
uint32_t high_block= 0, indev_blocks;
char name[24], *textpt, *contentpt, *buf= NULL, part_type_text[37];
char **lines= NULL;
double num[8];
char *cat_path= "";
struct elto_img_par *et_imgs= NULL;
int elto_count= 0;
uint32_t img_blocks= 0, mbr_parts_end= 0, iso_part_blocks;
uint32_t mbr_parts_end= 0, extract_size;
struct FindjoB *job= NULL;
struct stat dir_stbuf;
IsoImage *image;
@ -1681,7 +1696,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
char **app_pseudo_paths= NULL;
struct tm tm_erg;
int was_force_bootable= 0, have_mbr_force_bootable= 0;
uint64_t gpt_bheader_block= 0;
uint64_t gpt_bheader_block= 0, start_block, num_blocks;
uint64_t img_blocks= 0, iso_part_blocks;
struct mbr_par {
uint8_t ptype;
@ -1714,14 +1730,26 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
#define Xorriso_record_cmd_linE { \
ret= Xorriso_record_cmd_line(xorriso, buf, cmds, cmd_count, flag & 1); \
buf[0]= 0; \
if(ret <= 0) \
goto ex; \
}
#define Xorriso_record_boot_imglinE { \
ret= Xorriso_record_cmd_line(xorriso, buf, boot_imgs, boot_img_count, \
flag & 1); \
buf[0]= 0; \
if(ret <= 0) \
goto ex; \
}
/* 2 exp 19 blocks = 1 GiB */
#define Xorriso_max_endless_uefi_sizE (1 << 19)
mkisofs= !!(flag & 2);
imported_iso= (!mkisofs) << 30;
*cmd_count= 0;
*boot_img_count= 0;
line_count= et_line_count + sa_line_count;
if(line_count <= 0)
{ret= 1; goto ex;}
@ -1780,7 +1808,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
if(ret < 0)
goto ex;
if(ret == 0)
high_block = img_blocks - 1;
high_block = img_blocks / 4 - 1;
if(elto_count > 0) {
Xorriso_alloc_meM(et_imgs, struct elto_img_par, elto_count);
@ -1869,6 +1897,12 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
if(strcmp(name, "El Torito cat path :") == 0) {
cat_path= textpt;
} else if(strcmp(name, "El Torito catalog :") == 0) {
strcpy(buf, "eltorito_catalog.img/");
Xorriso_add_offset_size(xorriso, buf, ((off_t) num[0]) * 2048,
((off_t) num[1]) * 2048, 0);
Xorriso_record_boot_imglinE
} else if(strcmp(name, "El Torito boot img :") == 0) {
/* Platform Id, bootability, emulation, load segment,
Hard disk emulation partition type, Load size
@ -1895,10 +1929,22 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
et_imgs[idx].path= et_imgs[idx].id_string= et_imgs[idx].sel_crit= "";
et_imgs[idx].do_gpt_basdat= et_imgs[idx].do_gpt_hfsplus= 0;
et_imgs[idx].do_apm_hfsplus= 0;
et_imgs[idx].extract_size= (et_imgs[idx].ldsiz + 3) / 4;
} else if(strcmp(name, "El Torito img path :") == 0) {
idx= num[0] - 1;
et_imgs[idx].path= textpt;
ret= Xorriso_iso_lstat(xorriso, et_imgs[idx].path, &dir_stbuf, 0);
if(ret == 0) {
extract_size = (dir_stbuf.st_size + 2047) / 2048;
if(extract_size > et_imgs[idx].extract_size)
et_imgs[idx].extract_size= extract_size;
}
} else if(strcmp(name, "El Torito img blks :") == 0) {
idx= num[0] - 1;
if(num[1] > et_imgs[idx].extract_size)
et_imgs[idx].extract_size= num[1];
} else if(strcmp(name, "El Torito img opts :") == 0) {
idx= num[0] - 1;
@ -1925,15 +1971,17 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
} else if(strcmp(name, "MBR partition :") == 0) {
sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu",
&partno, &part_status, &part_type, &start_block, &num_blocks);
&partno, &part_status, &part_type, &mbr_start_block,
&mbr_num_blocks);
idx= partno - 1;
mbrpts[idx].ptype= part_type;
mbrpts[idx].start_block= start_block;
mbrpts[idx].block_count= num_blocks;
if(num_blocks > 0 && start_block + num_blocks > mbr_parts_end)
mbr_parts_end= start_block + num_blocks;
if(start_block == partition_offset * 4 &&
(start_block + num_blocks) >= high_block * 4 && iso_mbr_part_type < 0)
mbrpts[idx].start_block= mbr_start_block;
mbrpts[idx].block_count= mbr_num_blocks;
if(mbr_num_blocks > 0 && mbr_start_block + mbr_num_blocks > mbr_parts_end)
mbr_parts_end= mbr_start_block + mbr_num_blocks;
if(mbr_start_block == partition_offset * 4 &&
(mbr_start_block + mbr_num_blocks) >= high_block * 4 &&
iso_mbr_part_type < 0)
iso_mbr_part_type = part_type;
} else if(strcmp(name, "MBR partition path :") == 0) {
@ -2040,6 +2088,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s",
imported_iso | ptable_killer);
Xorriso_record_cmd_linE
strcpy(buf, "mbr_code_isohybrid.img/");
Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 446, 0);
Xorriso_record_boot_imglinE
did_sysarea= 1;
}
if(strstr(textpt, "grub2-mbr") != NULL) {
@ -2050,6 +2101,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) 0, (uint64_t) 15, "s",
imported_iso | ptable_killer);
Xorriso_record_cmd_linE
strcpy(buf, "mbr_code_grub2.img/");
Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 446, 0);
Xorriso_record_boot_imglinE
did_sysarea= 1;
}
if(strstr(textpt, "protective-msdos-label") != NULL) {
@ -2100,16 +2154,18 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
} else if(strcmp(name, "MBR partition :") == 0) {
sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu",
&partno, &part_status, &part_type, &start_block, &num_blocks);
if(num_blocks > 0 && part_type != 0x00 && part_type != 0xee &&
(iso_part_blocks <= start_block ||
&partno, &part_status, &part_type, &mbr_start_block,
&mbr_num_blocks);
if(mbr_num_blocks > 0 && part_type != 0x00 && part_type != 0xee &&
(iso_part_blocks <= mbr_start_block ||
(have_protective_msdos && img_blocks == mbr_parts_end &&
partno > 1))) {
if(!appended_as_gpt) {
sprintf(buf, "-append_partition %lu 0x%lx ", partno, part_type);
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) start_block,
((uint64_t) start_block) + num_blocks - 1, "d",
imported_iso);
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) mbr_start_block,
((uint64_t) mbr_start_block) + mbr_num_blocks - 1,
"d", imported_iso);
Xorriso_record_cmd_linE
if(partno >= 1 && (int) partno <= mbr_count)
mbrpts[partno - 1].appended= 1;
@ -2118,21 +2174,36 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
#endif
}
if(part_type == 0xef) {
sprintf(buf, "mbr_part%lu_efi.img/", partno);
Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512,
((off_t) mbr_num_blocks) * 512, 0);
Xorriso_record_boot_imglinE
}
} else if(part_type == 0x41 && have_prep) {
if(mkisofs) {
sprintf(buf, "-prep-boot-part ");
} else {
sprintf(buf, "-boot_image any prep_boot_part=");
}
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) start_block,
((uint64_t) start_block) + num_blocks - 1, "d",
imported_iso);
Xorriso_add_intvl_adr(xorriso, buf, (uint64_t) mbr_start_block,
((uint64_t) mbr_start_block) + mbr_num_blocks - 1,
"d", imported_iso);
Xorriso_record_cmd_linE
sprintf(buf, "mbr_part%lu_prep.img/", partno);
Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512,
((off_t) mbr_num_blocks) * 512, 0);
Xorriso_record_boot_imglinE
} else if(part_type == 0xef) {
sprintf(buf, "mbr_part%lu_efi.img/", partno);
Xorriso_add_offset_size(xorriso, buf, ((off_t) mbr_start_block) * 512,
((off_t) mbr_num_blocks) * 512, 0);
Xorriso_record_boot_imglinE
}
if((part_status & 0x80) && !was_force_bootable) {
was_force_bootable= 1;
if(buf[0]) {
Xorriso_record_cmd_linE
buf[0]= 0;
}
if(mkisofs)
sprintf(buf, "--mbr-force-bootable");
@ -2145,7 +2216,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
sprintf(xorriso->info_text,
"Cannot make proposal to mark PReP partition by data file: ");
Text_shellsafe(textpt, xorriso->info_text, 1);
if(!(flag & 1))
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
continue;
}
@ -2159,7 +2230,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
sprintf(xorriso->info_text,
"Cannot make proposal to mark data file as MBR partition without being an El Torito boot image : ");
Text_shellsafe(textpt, xorriso->info_text, 1);
if(!(flag & 1))
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
} else {
for(gpt_idx= 0; gpt_idx < gpt_count; gpt_idx++) {
@ -2171,7 +2242,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
sprintf(xorriso->info_text,
"Cannot make proposal to mark data file as MBR partition without being in GPT : ");
Text_shellsafe(textpt, xorriso->info_text, 1);
if(!(flag & 1))
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
}
}
@ -2201,7 +2272,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
sprintf(xorriso->info_text,
"Cannot make proposal to mark data file as GPT partition : ");
Text_shellsafe(textpt, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
}
} else if(strcmp(name, "GPT start and size :") == 0) {
@ -2237,7 +2309,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
(uint64_t) (num[1] + num[2] - 1.0), "d",
imported_iso);
Xorriso_record_cmd_linE
buf[0]= 0;
#ifdef Not_any_more_because_padding_is_now_after_partitions
appended_partition= 1;
@ -2264,7 +2335,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
else
sprintf(buf, "-boot_image any part_like_isohybrid=on");
Xorriso_record_cmd_linE
buf[0]= 0;
part_like_isohybrid= 1;
appended_as_gpt= 0;
}
@ -2284,7 +2354,21 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
(uint64_t) (num[1] + num[2] - 1.0), "d",
imported_iso);
efi_boot_part= 2;
Xorriso_record_cmd_linE
}
if(gpts[idx].ptype == 2 &&
(img_blocks / 2 > num[2] || num[1] >= img_blocks)) {
/* Obviously not a HFS+ tree covering the ISO */
sprintf(buf, "gpt_part%d_hfsplus.img/", idx + 1);
Xorriso_add_offset_size(xorriso, buf, ((off_t) num[1]) * 512,
((off_t) num[2]) * 512, 0);
Xorriso_record_boot_imglinE
} else if(gpts[idx].ptype == 3) {
sprintf(buf, "gpt_part%d_efi.img/", idx + 1);
Xorriso_add_offset_size(xorriso, buf, ((off_t) num[1]) * 512,
((off_t) num[2]) * 512, 0);
Xorriso_record_boot_imglinE
}
} else if(strcmp(name, "APM block size :") == 0) {
@ -2326,7 +2410,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
else
sprintf(buf, "-hfsplus on");
Xorriso_record_cmd_linE
buf[0]= 0;
/* Report commands for blessings and creator-type */
ret= Findjob_new(&job, "/", 0);
@ -2383,9 +2466,9 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
partno= id_tag= perms= num_blocks= 0;
start_cyl= 0xffffffff;
sscanf(contentpt, "%lu 0x%lx 0x%lx %lu %lu",
&partno, &id_tag, &perms, &start_cyl, &num_blocks);
&partno, &id_tag, &perms, &start_cyl, &mbr_num_blocks);
if(partno > 0 && partno < 9 && start_cyl == 0 &&
num_blocks >= img_blocks - 600 && num_blocks <= img_blocks &&
mbr_num_blocks >= img_blocks - 600 && mbr_num_blocks <= img_blocks &&
((partno == 1 && id_tag == 4) || (partno > 1 && id_tag == 2)))
full_sparc_part|= (1 << (partno - 1));
@ -2434,7 +2517,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
if(!have_alpha_ldr_path) {
sprintf(xorriso->info_text,
"Cannot enable DEC Alpha boot loader because it is not a data file in the ISO filesystem");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
}
} else if(strcmp(name, "DEC Alpha ldr path :") == 0) {
@ -2483,7 +2567,8 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
} else if(!cared_for_sparc) {
sprintf(xorriso->info_text,
"Cannot enable SUN Disk Label because of non-trivial partition layout");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
if(!(flag & 5))
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
}
}
if(have_sysarea && !did_sysarea) {
@ -2497,6 +2582,11 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
Xorriso_record_cmd_linE
did_sysarea= 1;
}
if(have_sysarea) {
strcpy(buf, "systemarea.img/");
Xorriso_add_offset_size(xorriso, buf, (off_t) 0, (off_t) 16 * 2048, 0);
Xorriso_record_boot_imglinE
}
if(iso_mbr_part_type >= 0) {
if(mkisofs)
sprintf(buf, "-iso_mbr_part_type 0x%2.2x",
@ -2542,8 +2632,29 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
}
Xorriso_record_cmd_linE
for(idx= 0; idx < elto_count; idx++) {
if(strcmp(et_imgs[idx].pltf, "UEFI") == 0 &&
et_imgs[idx].extract_size <= 0) {
ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0);
if(ret > 0) {
if(indev_blocks > et_imgs[idx].lba &&
indev_blocks - et_imgs[idx].lba <= Xorriso_max_endless_uefi_sizE)
et_imgs[idx].extract_size= indev_blocks - et_imgs[idx].lba;
}
if(et_imgs[idx].extract_size <= 0)
continue;
}
sprintf(buf, "eltorito_img%d_", idx + 1);
for(j= 0; j < 4 && et_imgs[idx].pltf[j] != 0; j++) {
buf[strlen(buf) + 1]= 0;
buf[strlen(buf)]= tolower(et_imgs[idx].pltf[j]);
}
strcat(buf, ".img/");
Xorriso_add_offset_size(xorriso, buf, ((off_t) et_imgs[idx].lba) * 2048,
((off_t) et_imgs[idx].extract_size) * 2048, 0);
Xorriso_record_boot_imglinE
if(et_imgs[idx].ld_seg != 0 && et_imgs[idx].ld_seg != 0x07c0) {
if(!(flag & 1)) {
if(!(flag & 5)) {
sprintf(xorriso->info_text,
"Cannot enable EL Torito boot image #%d because its Load Segment is neither 0x0 nor 0x7c0",
idx + 1);
@ -2559,9 +2670,6 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
Xorriso_record_cmd_linE
}
if(et_imgs[idx].path[0] == 0) {
/* >>> need way to exploit El Torito img blks : */;
/* Check whether appended partition */;
for(i= 0; i < mbr_count; i++)
if((mbrpts[i].appended || !mbrpts[i].has_path) &&
@ -2613,8 +2721,15 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
et_imgs[idx].path= app_pseudo_paths[idx];
}
}
if (et_imgs[idx].path[0] == 0) {
if(!(flag & 1)) {
/* >>> need way to exploit .extract_size by cutting out from ISO */;
}
if (et_imgs[idx].path[0] == 0) {
if(!(flag & 5)) {
sprintf(xorriso->info_text,
"Cannot enable EL Torito boot image #%d because it is not a data file in the ISO filesystem",
idx + 1);
@ -2727,7 +2842,7 @@ static int Xorriso_scan_report_lines(struct XorrisO *xorriso,
}
after_el_torito:
if((apm_count > 0 && !cared_for_apm) && !(flag & 1)) {
if((apm_count > 0 && !cared_for_apm) && !(flag & 5)) {
sprintf(xorriso->info_text,
"Cannot make proposal to produce APM of loaded image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "SORRY", 0);
@ -2764,19 +2879,24 @@ ex:
return(ret);
#undef Xorriso_record_cmd_linE
#undef Xorriso_record_boot_imglinE
#undef Xorriso_max_endless_uefi_sizE
}
/* @param flag bit0= currently not significant:
report is about El Torito rather than System Area
bit1= report -as mkisofs options
bit15= dispose cmds
bit1= report -as mkisofs options in cmds
bit2= no sorry messages
bit15= dispose cmds and boot_imgs
*/
static int Xorriso_report_to_cmd(struct XorrisO *xorriso,
char **et_lines, int et_line_count,
char **sa_lines, int sa_line_count,
char ***cmds, int *cmd_count, int flag)
char ***cmds, int *cmd_count,
char ***boot_imgs, int *boot_img_count,
int flag)
{
int ret= 0, i;
@ -2788,20 +2908,29 @@ static int Xorriso_report_to_cmd(struct XorrisO *xorriso,
/* Count commands */
ret= Xorriso_scan_report_lines(xorriso, et_lines, et_line_count,
sa_lines, sa_line_count, *cmds, cmd_count,
1 | (flag & 2));
*boot_imgs, boot_img_count,
1 | (flag & 6));
if(ret <= 0)
goto ex;
if(*cmd_count <= 0)
if(*cmd_count <= 0 && *boot_img_count <= 0)
{ret= 2; goto ex;}
Xorriso_alloc_meM(*cmds, char *, *cmd_count);
for(i= 0; i < *cmd_count; i++)
(*cmds)[i]= NULL;
if(*cmd_count > 0) {
Xorriso_alloc_meM(*cmds, char *, *cmd_count);
for(i= 0; i < *cmd_count; i++)
(*cmds)[i]= NULL;
}
if(*boot_img_count > 0) {
Xorriso_alloc_meM(*boot_imgs, char *, *boot_img_count);
for(i= 0; i < *boot_img_count; i++)
(*boot_imgs)[i]= NULL;
}
/* Record commands */
ret= Xorriso_scan_report_lines(xorriso, et_lines, et_line_count,
sa_lines, sa_line_count, *cmds, cmd_count,
flag & 2);
*boot_imgs, boot_img_count,
flag & 6);
if(ret <= 0)
goto ex;
@ -2815,6 +2944,13 @@ ex:
Xorriso_free_meM(*cmds);
*cmds= NULL;
}
if(*boot_imgs != NULL) {
for(i= 0; i < *boot_img_count; i++)
if((*boot_imgs)[i] != NULL)
Xorriso_free_meM((*boot_imgs)[i]);
Xorriso_free_meM(*boot_imgs);
*boot_imgs= NULL;
}
}
return(ret);
}
@ -2839,8 +2975,9 @@ static void Xorriso_report_lines(struct XorrisO *xorriso,
int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag)
{
int ret, line_count, cmd_count= 0, et_line_count= 0, sa_line_count= 0;
int do_cmd= 0, as_mkisofs= 0, i, bin_count;
int do_cmd= 0, as_mkisofs= 0, i, bin_count, boot_img_count= 0;
char **lines = NULL, **et_lines= NULL, **sa_lines= NULL, **cmds= NULL;
char **boot_imgs= NULL;
uint8_t guid[16];
IsoImage *image;
@ -2885,10 +3022,12 @@ int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag)
if(do_cmd) {
ret= Xorriso_report_to_cmd(xorriso, et_lines, et_line_count,
sa_lines, sa_line_count, &cmds, &cmd_count,
&boot_imgs, &boot_img_count,
(flag & 1) | (as_mkisofs << 1));
if(ret <= 0)
goto ex;
}
} else if(strncmp(form, "gpt_crc_of:", 11) == 0 && !(flag & 1)) {
ret = Xorriso_gpt_crc(xorriso, form + 11, 0);
goto ex;
@ -2986,7 +3125,60 @@ int Xorriso_report_system_area(struct XorrisO *xorriso, char *form, int flag)
}
ret= 1;
ex:;
Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count, 1 << 15);
Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count,
&boot_imgs, &boot_img_count, 1 << 15);
if(et_lines != NULL)
iso_image_report_el_torito(NULL, &et_lines, &et_line_count, 1 << 15);
if(sa_lines != NULL)
iso_image_report_system_area(NULL, &sa_lines, &sa_line_count, 1 << 15);
return(ret);
}
/* @param flag bit15= dispose imgs
*/
int Xorriso_list_boot_images(struct XorrisO *xorriso,
char ***imgs, int *img_count, int flag)
{
int ret, cmd_count= 0, et_line_count= 0, sa_line_count= 0, boot_img_count= 0;
char **et_lines= NULL, **sa_lines= NULL, **cmds= NULL, **boot_imgs= NULL;
IsoImage *image;
if(flag & (1 << 15)) {
boot_imgs= *imgs;
boot_img_count= *img_count;
Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count,
&boot_imgs, &boot_img_count, 1 << 15);
*imgs= NULL;
*img_count= 0;
return(1);
}
*imgs= NULL;
*img_count= 0;
ret= Xorriso_get_volume(xorriso, &image, 0);
if(ret <= 0)
goto ex;
ret= iso_image_report_el_torito(image, &et_lines, &et_line_count, 0);
if(ret < 0)
goto ex;
ret= iso_image_report_system_area(image, &sa_lines, &sa_line_count, 0);
if(ret < 0)
goto ex;
ret= Xorriso_report_to_cmd(xorriso, et_lines, et_line_count,
sa_lines, sa_line_count, &cmds, &cmd_count,
&boot_imgs, &boot_img_count, 4);
if(ret <= 0)
goto ex;
*imgs= boot_imgs;
*img_count= boot_img_count;
boot_imgs= NULL;
boot_img_count= 0;
ret= 1;
ex:;
Xorriso_report_to_cmd(xorriso, NULL, 0, NULL, 0, &cmds, &cmd_count,
&boot_imgs, &boot_img_count, 1 << 15);
if(et_lines != NULL)
iso_image_report_el_torito(NULL, &et_lines, &et_line_count, 1 << 15);
if(sa_lines != NULL)

@ -647,6 +647,24 @@ ex:;
}
/* Command -extract_boot_images */
int Xorriso_option_extract_boot_images(struct XorrisO *xorriso,
char *disk_dir_path, int flag)
{
int ret;
if(xorriso->allow_restore <= 0) {
sprintf(xorriso->info_text,
"-extract_boot_images: image-to-disk copies are not enabled by option -osirrox"
);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
return(0);
}
ret= Xorriso_extract_boot_images(xorriso, disk_dir_path, 0);
return(ret);
}
/* Option -extract_cut */
int Xorriso_option_extract_cut(struct XorrisO *xorriso, char *iso_rr_path,
char *start, char *count, char *disk_path, int flag)
@ -2327,6 +2345,9 @@ int Xorriso_option_help(struct XorrisO *xorriso, int flag)
" -extract_cut iso_rr_path byte_offset byte_count disk_path",
" Copy a byte interval from iso_rr_path to disk_path.",
" This is governed in part by -check_media_defaults.",
" -extract_boot_images disk_path",
" Copy boot images into files in directory disk_path with",
" names which tell the role inside the ISO.",
" -cpx iso_rr_path [***] disk_path",
" Copy leaf file objects from ISO image to disk filesystem.",
" -cpax iso_rr_path [***] disk_path",

@ -542,6 +542,7 @@ int Xorriso_count_args(struct XorrisO *xorriso, int argc, char **argv,
"commit_eject","compliance","copyright_file",
"dev","dialog","disk_dev_ino","disk_pattern","displacement",
"drive_access","dummy","dvd_obs","early_stdio_test","ecma119_map","eject",
"extract_boot_images",
"iso_nowtime","iso_rr_pattern","file_name_limit","follow","format","fs",
"gid","grow_blindly","hardlinks",
"hfsplus","history","indev","in_charset","joliet","joliet_map",
@ -748,6 +749,7 @@ int Xorriso_cmd_sorting_rank(struct XorrisO *xorriso,
"* osirrox ISO-to-disk restore options:",
"osirrox", "extract", "extract_single", "extract_l", "extract_cut",
"extract_boot_images",
"cpx", "cpax", "cp_rx", "cp_rax", "paste_in", "concat",
"mount",
@ -1316,11 +1318,22 @@ next_command:;
(*idx)+= 2;
ret= Xorriso_option_extract(xorriso, arg1, arg2, 0);
} else if(strcmp(cmd,"extract_boot_images")==0) {
(*idx)+= 1;
if((*idx)>argc) {
sprintf(xorriso->info_text,
"-extract_boot_images: Empty disk_path cannot be used as target directory");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0;
} else {
ret= Xorriso_option_extract_boot_images(xorriso, arg1, 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");
"-extract_cut: Not enough arguments. Needed are: disk_path start count iso_rr_path");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0;
} else

@ -2332,7 +2332,8 @@ ex:;
}
/* @param flag bit1= for Xorriso_check_interval(): no pacifier messages
/* @param flag bit0= ignore node and img_path, operate on whole medium
bit1= for Xorriso_check_interval(): no pacifier messages
*/
int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
char *img_path, char *disk_path,
@ -2341,6 +2342,8 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
{
int ret, i, lba_count= 0, *start_lbas= NULL, *end_lbas= NULL, read_chunk= 16;
int lba, count, blocks, quality, spot, bad_extract= 0;
int data_to_skip= 0;
uint32_t indev_blocks;
off_t size= 0, file_base_bytes= 0, file_processed_bytes= 0, img_adr;
off_t new_file_base_bytes, upto_file_bytes, start_byte= 0;
off_t *section_sizes = NULL;
@ -2348,25 +2351,33 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
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,
&section_sizes, &size, 0);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, "File object ");
Text_shellsafe(img_path, xorriso->info_text, 1);
strcat(xorriso->info_text,
" is currently not a data file from the loaded image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
data_to_skip= img_offset % (off_t) 2048;
if(flag & 1) {
lba_count= 1;
Xorriso_alloc_meM(start_lbas, int, 1);
Xorriso_alloc_meM(end_lbas, int, 1);
Xorriso_alloc_meM(section_sizes, off_t, 1);
start_lbas[0]= 0;
ret= Xorriso_obtain_indev_readsize(xorriso, &indev_blocks, 0);
if(ret > 0)
end_lbas[0]= indev_blocks - 1;
else
end_lbas[0]= 0x7ffffffe;
size= ((off_t) end_lbas[0]) * 2048;
section_sizes[0]= size;
} else {
ret= Xorriso__start_end_lbas(node, &lba_count, &start_lbas, &end_lbas,
&section_sizes, &size, 0);
if(ret <= 0) {
Xorriso_process_msg_queues(xorriso,0);
sprintf(xorriso->info_text, "File object ");
Text_shellsafe(img_path, xorriso->info_text, 1);
strcat(xorriso->info_text,
" is currently not a data file from the loaded image");
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
goto ex;
}
}
if(img_offset + bytes < size && bytes > 0)
size= img_offset + bytes;
@ -2409,13 +2420,14 @@ int Xorriso_read_file_data(struct XorrisO *xorriso, IsoNode *node,
file_base_bytes= img_offset;
}
/* Eventually omit surplus blocks */
/* 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;
job->data_to_skip= data_to_skip;
data_to_skip= 0;
file_processed_bytes+= ((off_t) count) * (off_t) 2048;
ret= Xorriso_check_interval(xorriso, spotlist, job, lba, count, read_chunk,
0, (flag & 2));
@ -2471,6 +2483,103 @@ ex:;
}
int Xorriso_extract_boot_images(struct XorrisO *xorriso, char *disk_dir_path,
int flag)
{
int ret, img_count= 0, i, was_problem= 0;
char **imgs= NULL, *eff_path= NULL, *cpt, *eff_namept;
struct stat stbuf;
off_t byte_offset, byte_size;
Xorriso_alloc_meM(eff_path, char, SfileadrL);
ret= Xorriso_normalize_img_path(xorriso, xorriso->wdx, disk_dir_path,
eff_path, 2 | 4);
if(ret <= 0)
goto ex;
if(strlen(eff_path) > SfileadrL - 80) {
sprintf(xorriso->info_text,
"-extract_boot_images: disk_path is too long (%lu)\n",
(unsigned long int) strlen(eff_path));
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
ret= stat(eff_path, &stbuf);
if(ret == 0) {
if(!S_ISDIR(stbuf.st_mode)) {
sprintf(xorriso->info_text,
"-extract_boot_images: disk_path is not a directory : ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, 0, "FAILURE", 0);
ret= 0; goto ex;
}
} else {
ret= mkdir(eff_path, 0777);
if(ret == -1) {
sprintf(xorriso->info_text,
"-extract_boot_images: cannot create directory : ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
ret= 0; goto ex;
}
}
strcat(eff_path, "/");
eff_namept= eff_path + strlen(eff_path);
ret= Xorriso_list_boot_images(xorriso, &imgs, &img_count, 0);
if(ret <= 0)
goto ex;
/* Interpret list and create files */
for(i= 0; i < img_count; i++) {
ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
if(ret < 0)
{ret= 0; goto ex;}
cpt= strchr(imgs[i], '/');
if(cpt == NULL)
continue;
*cpt= 0;
cpt+= 2;
ret= Sfile_text_to_off_t(cpt, &byte_offset, 0);
if(ret <= 0)
continue;
cpt+= ret;
if(*cpt == 0)
continue;
cpt++;
ret= Sfile_text_to_off_t(cpt, &byte_size, 0);
if(ret <= 0)
continue;
strcpy(eff_namept, imgs[i]);
sprintf(xorriso->info_text, "%s : offset=%.f size=%.f\n",
eff_path, (double) byte_offset, (double) byte_size);
Xorriso_info(xorriso, 0);
ret= stat(eff_path, &stbuf);
if(ret != -1) {
sprintf(xorriso->info_text,
"-extract_boot_images: File already exists on disk: ");
Text_shellsafe(eff_path, xorriso->info_text, 1);
Xorriso_msgs_submit(xorriso, 0, xorriso->info_text, errno, "FAILURE", 0);
continue;
}
ret= Xorriso_read_file_data(xorriso, NULL, NULL, eff_path,
byte_offset, (off_t) 0, byte_size, 1);
if(ret <= 0)
was_problem= 1;
}
ret= Xorriso_eval_problem_status(xorriso, 1, 1 | 2);
if(ret < 0 || was_problem)
{ret= 0; goto ex;}
ret= 1;
ex:;
Xorriso_free_meM(eff_path);
Xorriso_list_boot_images(xorriso, &imgs, &img_count, 1 << 15);
return(ret);
}
/* @param node Opaque handle to IsoNode which is to be inquired instead of path if it is not NULL.
@param path is used as address if node is NULL.
@param flag bit0= do not report to result but only indicate outcome

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -430,6 +430,32 @@ int Sfile_off_t_text(char text[80], off_t num, int flag)
}
/* @return index number of first not interpreted text byte
*/
int Sfile_text_to_off_t(char *text, off_t *num, int flag)
{
int sig= 1, ridx;
*num= 0;
ridx= 0;
if(text[ridx] == '-') {
sig= -1;
ridx++;
} else if(text[ridx] == '+') {
ridx++;
}
for(; text[ridx] != 0; ridx++) {
if(text[ridx] < '0' || text[ridx] > '9')
break;
if(*num > (((off_t) 1) << 59))
return(-1);
*num= *num * 10 + text[ridx] - '0';
}
*num= *num * sig;
return(ridx);
}
/* Converts backslash codes into single characters:
\a BEL 7 , \b BS 8 , \e ESC 27 , \f FF 12 , \n LF 10 , \r CR 13 ,
\t HT 9 , \v VT 11 , \\ \ 92

@ -1,7 +1,7 @@
/* xorriso - creates, loads, manipulates and burns ISO 9660 filesystem images.
Copyright 2007-2014 Thomas Schmitt, <scdbackup@gmx.net>
Copyright 2007-2020 Thomas Schmitt, <scdbackup@gmx.net>
Provided under GPL version 2 or later.
@ -105,6 +105,7 @@ int Sfile_sep_make_argv(char *progname, char *line, char *separators,
int Sfile_decode_datestr(struct tm *reply, char *text, int flag);
int Sfile_off_t_text(char text[80], off_t num, int flag);
int Sfile_text_to_off_t(char *text, off_t *num, int flag);
int Sfile_leafname(char *path, char leafname[SfileadrL], int flag);

@ -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, Nov 20, 2020"
.TH XORRISO 1 "Version 1.5.3, Nov 30, 2020"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
@ -5132,6 +5132,43 @@ word are used as arguments with the program start. Example:
The further parameters in all modes are the is